diff --git a/Telegram/BUILD b/Telegram/BUILD
index af18262d33..7220af61dc 100644
--- a/Telegram/BUILD
+++ b/Telegram/BUILD
@@ -309,6 +309,8 @@ alternate_icon_folders = [
"PremiumTurbo",
]
+composer_icon_folders = ["Telegram"]
+
[
filegroup(
name = "{}".format(name),
@@ -318,6 +320,15 @@ alternate_icon_folders = [
) for name in alternate_icon_folders
]
+[
+ filegroup(
+ name = "{}_icon".format(name),
+ srcs = glob([
+ "Telegram-iOS/{}.icon/**/*".format(name),
+ ]),
+ ) for name in composer_icon_folders
+]
+
filegroup(
name = "LaunchScreen",
srcs = glob([
@@ -1699,12 +1710,13 @@ ios_application(
":RequiredDeviceCapabilitiesPlist",
":UrlTypesInfoPlist",
],
+ app_icons = [ ":{}_icon".format(name) for name in composer_icon_folders ],
alternate_icons = [
":{}".format(name) for name in alternate_icon_folders
],
resources = [
":LaunchScreen",
- ":DefaultAppIcon",
+ #":DefaultAppIcon",
],
frameworks = [
":MtProtoKitFramework",
diff --git a/Telegram/Telegram-iOS/Telegram.icon/Assets/Oval.svg b/Telegram/Telegram-iOS/Telegram.icon/Assets/Oval.svg
new file mode 100644
index 0000000000..c3e47858d3
--- /dev/null
+++ b/Telegram/Telegram-iOS/Telegram.icon/Assets/Oval.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/Telegram/Telegram-iOS/Telegram.icon/Assets/Plane.svg b/Telegram/Telegram-iOS/Telegram.icon/Assets/Plane.svg
new file mode 100644
index 0000000000..e475bcfde7
--- /dev/null
+++ b/Telegram/Telegram-iOS/Telegram.icon/Assets/Plane.svg
@@ -0,0 +1,7 @@
+
+
\ No newline at end of file
diff --git a/Telegram/Telegram-iOS/Telegram.icon/icon.json b/Telegram/Telegram-iOS/Telegram.icon/icon.json
new file mode 100644
index 0000000000..b1143f6343
--- /dev/null
+++ b/Telegram/Telegram-iOS/Telegram.icon/icon.json
@@ -0,0 +1,122 @@
+{
+ "fill" : "system-light",
+ "groups" : [
+ {
+ "blend-mode" : "normal",
+ "blur-material" : 1,
+ "layers" : [
+ {
+ "blend-mode-specializations" : [
+ {
+ "value" : "normal"
+ },
+ {
+ "appearance" : "dark",
+ "value" : "normal"
+ }
+ ],
+ "fill-specializations" : [
+ {
+ "appearance" : "dark",
+ "value" : "automatic"
+ }
+ ],
+ "glass" : true,
+ "image-name" : "Plane.svg",
+ "name" : "Plane",
+ "position-specializations" : [
+ {
+ "idiom" : "watchOS",
+ "value" : {
+ "scale" : 1.35,
+ "translation-in-points" : [
+ 0,
+ 0
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "blend-mode-specializations" : [
+ {
+ "value" : "normal"
+ },
+ {
+ "appearance" : "dark",
+ "value" : "normal"
+ }
+ ],
+ "fill-specializations" : [
+ {
+ "value" : {
+ "linear-gradient" : [
+ "display-p3:0.21569,0.68627,0.89020,1.00000",
+ "srgb:0.11373,0.57647,0.82353,1.00000"
+ ]
+ }
+ },
+ {
+ "appearance" : "dark",
+ "value" : {
+ "automatic-gradient" : "srgb:0.00000,0.47843,1.00000,1.00000"
+ }
+ }
+ ],
+ "glass" : true,
+ "hidden-specializations" : [
+ {
+ "value" : false
+ },
+ {
+ "idiom" : "watchOS",
+ "value" : false
+ }
+ ],
+ "image-name" : "Oval.svg",
+ "name" : "Oval",
+ "position-specializations" : [
+ {
+ "idiom" : "watchOS",
+ "value" : {
+ "scale" : 2,
+ "translation-in-points" : [
+ 0,
+ 0
+ ]
+ }
+ }
+ ]
+ }
+ ],
+ "lighting" : "combined",
+ "position-specializations" : [
+ {
+ "idiom" : "watchOS",
+ "value" : {
+ "scale" : 1,
+ "translation-in-points" : [
+ 0,
+ 0
+ ]
+ }
+ }
+ ],
+ "shadow" : {
+ "kind" : "layer-color",
+ "opacity" : 1
+ },
+ "specular" : true,
+ "translucency" : {
+ "enabled" : false,
+ "value" : 1
+ }
+ }
+ ],
+ "supported-platforms" : {
+ "circles" : [
+ "watchOS"
+ ],
+ "squares" : "shared"
+ }
+}
\ No newline at end of file
diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings
index 932ddc3e51..29050a4419 100644
--- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings
+++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings
@@ -15077,3 +15077,14 @@ Error: %8$@";
"Conversation.SuggestedBirthdate.View" = "View";
"PeerInfo.ChangeProfileColor" = "Change Profile Color";
+
+"PUSH_MESSAGE_TODO" = "%1$@|sent you a todo-list %2$@";
+"PUSH_CHANNEL_MESSAGE_TODO" = "%1$@|posted a todo-list %2$@";
+"PUSH_CHANNEL_MESSAGE_TODO_DONE" = "%1$@|toggled %2$@ tasks";
+"PUSH_CHANNEL_MESSAGE_TODO_APPEND" = "%1$@|added %2$@ tasks";
+"PUSH_CHAT_MESSAGE_TODO" = "%2$@|%1$@ sent a todo-list %3$@";
+"PUSH_CHAT_MESSAGE_TODO_DONE" = "%2$@|%1$@ toggled %3$@ tasks";
+"PUSH_CHAT_MESSAGE_TODO_APPEND" = "%2$@|%1$@ added %3$@ tasks";
+"PUSH_PINNED_TODO" = "%1$@|pinned a todo-list %2$@";
+"PUSH_REACT_TODO" = "%1$@|reacted %2$@ to your todo %3$@";
+"PUSH_CHAT_REACT_TODO" = "%2$@|%1$@ reacted %3$@ to your todo %4$@";
diff --git a/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift b/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift
index 261ccc1b6d..cfcd09a668 100644
--- a/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift
+++ b/submodules/AttachmentTextInputPanelNode/Sources/AttachmentTextInputPanelNode.swift
@@ -700,6 +700,9 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
let hadLayout = self.validLayout != nil
let previousAdditionalSideInsets = self.validLayout?.3
self.validLayout = (width, leftInset, rightInset, additionalSideInsets, maxHeight, metrics, isSecondary)
+
+ let leftInset = leftInset + 8.0
+ let rightInset = rightInset + 8.0
var transition = transition
if let previousAdditionalSideInsets = previousAdditionalSideInsets, previousAdditionalSideInsets.right != additionalSideInsets.right {
@@ -933,9 +936,13 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
}
private func updateFieldAndButtonsLayout(inputHasText: Bool, panelHeight: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat {
- guard let (width, leftInset, rightInset, additionalSideInsets, _, metrics, _) = self.validLayout else {
+ guard let (width, leftInsetValue, rightInsetValue, additionalSideInsets, _, metrics, _) = self.validLayout else {
return 0.0
}
+
+ let leftInset = leftInsetValue + 8.0
+ let rightInset = rightInsetValue + 8.0
+
var textFieldMinHeight: CGFloat = 33.0
if let presentationInterfaceState = self.presentationInterfaceState {
textFieldMinHeight = calclulateTextFieldMinHeight(presentationInterfaceState, metrics: metrics)
@@ -1280,6 +1287,9 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
if let (width, leftInset, rightInset, _, maxHeight, metrics, _) = self.validLayout {
let composeButtonsOffset: CGFloat = 0.0
+ let leftInset = leftInset + 8.0
+ let rightInset = rightInset + 8.0
+
let (_, textFieldHeight) = self.calculateTextFieldMetrics(width: width - leftInset - rightInset, maxHeight: maxHeight, metrics: metrics)
let panelHeight = self.panelHeight(textFieldHeight: textFieldHeight, metrics: metrics)
var textFieldMinHeight: CGFloat = 33.0
@@ -1421,6 +1431,9 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
private func updateTextHeight(animated: Bool) -> CGFloat? {
if let (width, leftInset, rightInset, additionalSideInsets, maxHeight, metrics, _) = self.validLayout {
+ let leftInset = leftInset + 8.0
+ let rightInset = rightInset + 8.0
+
let (_, textFieldHeight) = self.calculateTextFieldMetrics(width: width - leftInset - rightInset - additionalSideInsets.right, maxHeight: maxHeight, metrics: metrics)
let panelHeight = self.panelHeight(textFieldHeight: textFieldHeight, metrics: metrics)
if !self.bounds.size.height.isEqual(to: panelHeight) {
diff --git a/submodules/ChatListUI/Sources/Node/ChatListItem.swift b/submodules/ChatListUI/Sources/Node/ChatListItem.swift
index 9eab22c3d7..933db76461 100644
--- a/submodules/ChatListUI/Sources/Node/ChatListItem.swift
+++ b/submodules/ChatListUI/Sources/Node/ChatListItem.swift
@@ -124,14 +124,16 @@ public enum ChatListItemContent {
public var hideSeparator: Bool
public var hideDate: Bool
public var hidePeerStatus: Bool
+ public var isInTransparentContainer: Bool
- public init(commandPrefix: String?, searchQuery: String?, messageCount: Int?, hideSeparator: Bool, hideDate: Bool, hidePeerStatus: Bool) {
+ public init(commandPrefix: String?, searchQuery: String?, messageCount: Int?, hideSeparator: Bool, hideDate: Bool, hidePeerStatus: Bool, isInTransparentContainer: Bool = false) {
self.commandPrefix = commandPrefix
self.searchQuery = searchQuery
self.messageCount = messageCount
self.hideSeparator = hideSeparator
self.hideDate = hideDate
self.hidePeerStatus = hidePeerStatus
+ self.isInTransparentContainer = isInTransparentContainer
}
}
@@ -1966,6 +1968,11 @@ public class ChatListItemNode: ItemListRevealOptionsItemNode {
reallyHighlighted = true
}
}
+ if case let .peer(peerData) = item.content, let customMessageListData = peerData.customMessageListData {
+ if customMessageListData.isInTransparentContainer {
+ reallyHighlighted = false
+ }
+ }
}
return reallyHighlighted
}
diff --git a/submodules/Display/Source/CAAnimationUtils.swift b/submodules/Display/Source/CAAnimationUtils.swift
index 73cc4f6e26..11d512fa51 100644
--- a/submodules/Display/Source/CAAnimationUtils.swift
+++ b/submodules/Display/Source/CAAnimationUtils.swift
@@ -104,7 +104,34 @@ public extension CALayer {
return animation
} else if timingFunction == kCAMediaTimingFunctionSpring {
- if duration == 0.5 {
+ if #available(iOS 26.0, *) {
+ let animation = make26SpringAnimationImpl(keyPath, duration)
+ animation.fromValue = from
+ animation.toValue = to
+ animation.isRemovedOnCompletion = removeOnCompletion
+ animation.fillMode = .forwards
+ if let completion {
+ animation.delegate = CALayerAnimationDelegate(animation: animation, completion: completion)
+ }
+
+ let k = Float(UIView.animationDurationFactor())
+ var speed: Float = 1.0
+ if k != 0 && k != 1 {
+ speed = Float(1.0) / k
+ }
+
+ animation.speed = speed * Float(animation.duration / duration)
+ animation.isAdditive = additive
+
+ if !delay.isZero {
+ animation.beginTime = self.convertTime(CACurrentMediaTime(), from: nil) + delay * UIView.animationDurationFactor()
+ animation.fillMode = .both
+ }
+
+ adjustFrameRate(animation: animation)
+
+ return animation
+ } else if duration == 0.5 {
let animation = makeSpringAnimation(keyPath)
animation.fromValue = from
animation.toValue = to
diff --git a/submodules/Display/Source/UIKitUtils.swift b/submodules/Display/Source/UIKitUtils.swift
index 0b109eb7d1..229b9b77f0 100644
--- a/submodules/Display/Source/UIKitUtils.swift
+++ b/submodules/Display/Source/UIKitUtils.swift
@@ -900,3 +900,54 @@ public extension CGPoint {
return CGPoint(x: self.x + dx, y: self.y + dy)
}
}
+
+public extension UIView {
+ func setMonochromaticEffect(tintColor: UIColor?) {
+ var overrideUserInterfaceStyle: UIUserInterfaceStyle = .unspecified
+ var red: CGFloat = 0.0
+ var green: CGFloat = 0.0
+ var blue: CGFloat = 0.0
+ var alpha: CGFloat = 1.0
+ if let tintColor {
+ if tintColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha) {
+ if red == 0.0 && green == 0.0 && blue == 0.0 && alpha == 1.0 {
+ overrideUserInterfaceStyle = .light
+ }
+ } else {
+ if red == 1.0 && green == 1.0 && blue == 1.0 && alpha == 1.0 {
+ overrideUserInterfaceStyle = .dark
+ }
+ }
+ }
+
+ if self.overrideUserInterfaceStyle != overrideUserInterfaceStyle {
+ self.overrideUserInterfaceStyle = overrideUserInterfaceStyle
+ setMonochromaticEffectImpl(self, overrideUserInterfaceStyle != .unspecified)
+ }
+ }
+
+ func setMonochromaticEffectAndAlpha(tintColor: UIColor?, transition: ContainedViewLayoutTransition) {
+ var overrideUserInterfaceStyle: UIUserInterfaceStyle = .unspecified
+ var red: CGFloat = 0.0
+ var green: CGFloat = 0.0
+ var blue: CGFloat = 0.0
+ var alpha: CGFloat = 1.0
+ if let tintColor {
+ if tintColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha) {
+ if red == 0.0 && green == 0.0 && blue == 0.0 {
+ overrideUserInterfaceStyle = .light
+ }
+ } else {
+ if red == 1.0 && green == 1.0 && blue == 1.0 {
+ overrideUserInterfaceStyle = .dark
+ }
+ }
+ }
+
+ if self.overrideUserInterfaceStyle != overrideUserInterfaceStyle {
+ self.overrideUserInterfaceStyle = overrideUserInterfaceStyle
+ setMonochromaticEffectImpl(self, overrideUserInterfaceStyle != .unspecified)
+ }
+ transition.updateAlpha(layer: self.layer, alpha: alpha)
+ }
+}
diff --git a/submodules/Display/Source/WindowContent.swift b/submodules/Display/Source/WindowContent.swift
index e5270bdae2..9eab40c43a 100644
--- a/submodules/Display/Source/WindowContent.swift
+++ b/submodules/Display/Source/WindowContent.swift
@@ -604,7 +604,10 @@ public class Window1 {
var duration: Double = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0.0
if duration > Double.ulpOfOne {
- duration = 0.5
+ if #available(iOS 26.0, *) {
+ } else {
+ duration = 0.5
+ }
}
let curve: UInt = (notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.uintValue ?? 7
diff --git a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift
index cfca87664f..18a195c993 100644
--- a/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift
+++ b/submodules/TelegramCallsUI/Sources/VideoChatScreen.swift
@@ -2232,7 +2232,7 @@ final class VideoChatScreenComponent: Component {
color: .white
)),
background: AnyComponent(
- GlassBackgroundComponent(size: CGSize(width: navigationButtonDiameter, height: navigationButtonDiameter), tintColor: .init(kind: .custom, color: UIColor(rgb: 0x101014)))
+ GlassBackgroundComponent(size: CGSize(width: navigationButtonDiameter, height: navigationButtonDiameter), isDark: true, tintColor: .init(kind: .custom, color: UIColor(rgb: 0x101014)))
),
effectAlignment: .center,
minSize: CGSize(width: navigationButtonDiameter, height: navigationButtonDiameter),
@@ -2254,7 +2254,7 @@ final class VideoChatScreenComponent: Component {
image: closeButtonImage(dark: false)
)),
background: AnyComponent(
- GlassBackgroundComponent(size: CGSize(width: navigationButtonDiameter, height: navigationButtonDiameter), tintColor: .init(kind: .custom, color: UIColor(rgb: 0x101014)))
+ GlassBackgroundComponent(size: CGSize(width: navigationButtonDiameter, height: navigationButtonDiameter), isDark: true, tintColor: .init(kind: .custom, color: UIColor(rgb: 0x101014)))
),
effectAlignment: .center,
minSize: CGSize(width: navigationButtonDiameter, height: navigationButtonDiameter),
diff --git a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift
index 97f506b2a3..b38b9de3bd 100644
--- a/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift
+++ b/submodules/TelegramPresentationData/Sources/DefaultDarkPresentationTheme.swift
@@ -663,14 +663,14 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
panelBackgroundColorNoWallpaper: UIColor(rgb: 0x000000),
panelSeparatorColor: UIColor(rgb: 0x545458, alpha: 0.55),
panelControlAccentColor: UIColor(rgb: 0xffffff),
- panelControlColor: UIColor(rgb: 0x808080),
+ panelControlColor: UIColor(rgb: 0xffffff),
panelControlDisabledColor: UIColor(rgb: 0x808080, alpha: 0.5),
panelControlDestructiveColor: UIColor(rgb: 0xff3b30),
inputBackgroundColor: UIColor(rgb: 0x060606),
inputStrokeColor: UIColor(rgb: 0xffffff, alpha: 0.1),
inputPlaceholderColor: UIColor(rgb: 0x7b7b7b),
inputTextColor: UIColor(rgb: 0xffffff),
- inputControlColor: UIColor(rgb: 0x7b7b7b),
+ inputControlColor: UIColor(rgb: 0xffffff),
actionControlFillColor: UIColor(rgb: 0xffffff),
actionControlForegroundColor: UIColor(rgb: 0x000000),
primaryTextColor: UIColor(rgb: 0xffffff),
diff --git a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift
index a8848b51ae..5bfbee3634 100644
--- a/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift
+++ b/submodules/TelegramPresentationData/Sources/DefaultDayPresentationTheme.swift
@@ -943,17 +943,17 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
panelBackgroundColorNoWallpaper: UIColor(rgb: 0xffffff),
panelSeparatorColor: UIColor(white: 1.0, alpha: 0.5),
panelControlAccentColor: defaultDayAccentColor,
- panelControlColor: UIColor(rgb: 0x858e99),
+ panelControlColor: UIColor(rgb: 0x000000, alpha: 1.0),
panelControlDisabledColor: UIColor(rgb: 0x727b87, alpha: 0.5),
panelControlDestructiveColor: UIColor(rgb: 0xff3b30),
inputBackgroundColor: UIColor(rgb: 0xffffff),
inputStrokeColor: UIColor(rgb: 0x000000, alpha: 0.1),
- inputPlaceholderColor: UIColor(rgb: 0x202020, alpha: 0.4),
+ inputPlaceholderColor: UIColor(rgb: 0x000000, alpha: 0.4),
inputTextColor: UIColor(rgb: 0x000000),
- inputControlColor: UIColor(rgb: 0x202020, alpha: 0.6),
+ inputControlColor: UIColor(rgb: 0x000000, alpha: 1.0),
actionControlFillColor: defaultDayAccentColor,
actionControlForegroundColor: UIColor(rgb: 0xffffff),
- primaryTextColor: UIColor(rgb: 0x000000, alpha: 0.9),
+ primaryTextColor: UIColor(rgb: 0x000000, alpha: 1.0),
secondaryTextColor: UIColor(rgb: 0x202020, alpha: 0.6),
mediaRecordingDotColor: UIColor(rgb: 0xed2521),
mediaRecordingControl: inputPanelMediaRecordingControl
diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift
index fbb1e283bb..72528395d0 100644
--- a/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatMessageActionBubbleContentNode/Sources/ChatMessageActionBubbleContentNode.swift
@@ -57,6 +57,10 @@ public class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode {
private var cachedMaskBackgroundImage: (CGPoint, UIImage, [CGRect])?
private var absoluteRect: (CGRect, CGSize)?
+ override public var disablesClipping: Bool {
+ return true
+ }
+
override public var visibility: ListViewItemNodeVisibility {
didSet {
if oldValue != self.visibility {
diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift
index 61f056323c..547b785ab5 100644
--- a/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatMessageBubbleItemNode/Sources/ChatMessageBubbleItemNode.swift
@@ -3442,14 +3442,14 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
contentContainerNodeFrames: contentContainerNodeFrames.map { containerGroupId, containerFrame, currentItemSelection, currentContainerGroupOverlap in
return (containerGroupId, containerFrame.offsetBy(dx: 0.0, dy: layoutInsets.top), currentItemSelection, currentContainerGroupOverlap)
},
- mosaicStatusOrigin: mosaicStatusOrigin?.offsetBy(dx: 0.0, dy: layoutInsets.top),
+ mosaicStatusOrigin: mosaicStatusOrigin,
mosaicStatusSizeAndApply: mosaicStatusSizeAndApply,
- unlockButtonPosition: unlockButtonPosition?.offsetBy(dx: 0.0, dy: layoutInsets.top),
+ unlockButtonPosition: unlockButtonPosition?.offsetBy(dx: 0.0, dy: layoutInsets.top),
unlockButtonSizeAndApply: unlockButtonSizeApply,
mediaInfoOrigin: mediaInfoOrigin?.offsetBy(dx: 0.0, dy: layoutInsets.top),
mediaInfoSizeAndApply: mediaInfoSizeApply,
needsShareButton: needsShareButton,
- shareButtonOffset: shareButtonOffset?.offsetBy(dx: 0.0, dy: layoutInsets.top),
+ shareButtonOffset: shareButtonOffset,
avatarOffset: avatarOffset,
hidesHeaders: hidesHeaders,
disablesComments: disablesComments,
diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift
index 1a19cf132f..61b827f232 100644
--- a/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatMessageGiftBubbleContentNode/Sources/ChatMessageGiftBubbleContentNode.swift
@@ -86,6 +86,10 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
private var currentProgressDisposable: Disposable?
+ override public var disablesClipping: Bool {
+ return true
+ }
+
override public var visibility: ListViewItemNodeVisibility {
didSet {
let wasVisible = oldValue != .none
diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift
index 14cd78cf46..89a2d43fb0 100644
--- a/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatMessageSelectionInputPanelNode/Sources/ChatMessageSelectionInputPanelNode.swift
@@ -449,10 +449,10 @@ public final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded)
var leftInset = leftInset
- leftInset += 8.0
+ leftInset += 16.0
var rightInset = rightInset
- rightInset += 8.0
+ rightInset += 16.0
let panelHeight = defaultHeight(metrics: metrics)
diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift
index 8f94a44ff8..d54bbcfe41 100644
--- a/submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatTextInputActionButtonsNode/Sources/ChatTextInputActionButtonsNode.swift
@@ -197,6 +197,7 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
self.expandMediaInputButtonBackgroundView.contentView.addSubview(self.expandMediaInputButtonIcon)
self.expandMediaInputButtonIcon.image = PresentationResourcesChat.chatInputPanelExpandButtonImage(presentationInterfaceState.theme)
self.expandMediaInputButtonIcon.tintColor = theme.chat.inputPanel.inputControlColor
+ self.expandMediaInputButtonIcon.setMonochromaticEffect(tintColor: theme.chat.inputPanel.inputControlColor)
super.init()
@@ -265,6 +266,7 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
public func updateTheme(theme: PresentationTheme, wallpaper: TelegramWallpaper) {
self.micButton.updateTheme(theme: theme)
self.expandMediaInputButtonIcon.tintColor = theme.chat.inputPanel.inputControlColor
+ self.expandMediaInputButtonIcon.setMonochromaticEffect(tintColor: theme.chat.inputPanel.inputControlColor)
}
private var absoluteRect: (CGRect, CGSize)?
@@ -352,8 +354,8 @@ public final class ChatTextInputActionButtonsNode: ASDisplayNode, ChatSendMessag
self.expandMediaInputButtonBackgroundView.update(size: size, cornerRadius: size.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: ComponentTransition(transition))
if let image = self.expandMediaInputButtonIcon.image {
let expandIconFrame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) * 0.5), y: floor((size.height - image.size.height) * 0.5)), size: image.size)
- transition.updatePosition(layer: self.expandMediaInputButtonIcon.layer, position: expandIconFrame.center)
- transition.updateBounds(layer: self.expandMediaInputButtonIcon.layer, bounds: CGRect(origin: CGPoint(), size: expandIconFrame.size))
+ self.expandMediaInputButtonIcon.center = expandIconFrame.center
+ self.expandMediaInputButtonIcon.bounds = CGRect(origin: CGPoint(), size: expandIconFrame.size)
transition.updateTransformScale(layer: self.expandMediaInputButtonIcon.layer, scale: CGPoint(x: 1.0, y: isMediaInputExpanded ? 1.0 : -1.0))
}
diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/AccessoryItemIconButton.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/AccessoryItemIconButton.swift
index 84218bb179..74bb336023 100644
--- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/AccessoryItemIconButton.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/AccessoryItemIconButton.swift
@@ -16,8 +16,7 @@ final class AccessoryItemIconButton: HighlightTrackingButton, GlassBackgroundVie
private var theme: PresentationTheme
private var strings: PresentationStrings
private var width: CGFloat
- private let iconImageView: UIImageView
- private let tintMaskIconImageView: UIImageView
+ private let iconImageView: GlassBackgroundView.ContentImageView
private var textView: ImmediateTextView?
private var tintMaskTextView: ImmediateTextView?
private var animationView: ComponentView?
@@ -34,8 +33,7 @@ final class AccessoryItemIconButton: HighlightTrackingButton, GlassBackgroundVie
self.theme = theme
self.strings = strings
- self.iconImageView = UIImageView()
- self.tintMaskIconImageView = UIImageView()
+ self.iconImageView = GlassBackgroundView.ContentImageView()
let (image, text, accessibilityLabel, alpha, _) = AccessoryItemIconButton.imageAndInsets(item: item, theme: theme, strings: strings)
@@ -51,12 +49,11 @@ final class AccessoryItemIconButton: HighlightTrackingButton, GlassBackgroundVie
self.iconImageView.isUserInteractionEnabled = false
self.addSubview(self.iconImageView)
- self.tintMask.addSubview(self.tintMaskIconImageView)
+ self.tintMask.addSubview(self.iconImageView.tintMask)
switch item {
case .input, .botInput, .silentPost:
self.iconImageView.isHidden = true
- self.tintMaskIconImageView.isHidden = self.iconImageView.isHidden
self.animationView = ComponentView()
self.tintMaskAnimationView = UIImageView()
default:
@@ -93,10 +90,6 @@ final class AccessoryItemIconButton: HighlightTrackingButton, GlassBackgroundVie
self.iconImageView.tintColor = theme.chat.inputPanel.inputControlColor
self.iconImageView.alpha = alpha
- self.tintMaskIconImageView.image = self.iconImageView.image
- self.tintMaskIconImageView.tintColor = .black
- self.tintMaskIconImageView.alpha = self.iconImageView.alpha
-
self.accessibilityLabel = accessibilityLabel
self.highligthedChanged = { [weak self] highlighted in
@@ -138,10 +131,6 @@ final class AccessoryItemIconButton: HighlightTrackingButton, GlassBackgroundVie
self.iconImageView.tintColor = theme.chat.inputPanel.inputControlColor
self.iconImageView.alpha = alpha
- self.tintMaskIconImageView.image = self.iconImageView.image
- self.tintMaskIconImageView.tintColor = .black
- self.tintMaskIconImageView.alpha = self.iconImageView.alpha
-
self.accessibilityLabel = accessibilityLabel
}
@@ -205,12 +194,13 @@ final class AccessoryItemIconButton: HighlightTrackingButton, GlassBackgroundVie
if let image = self.iconImageView.image {
self.iconImageView.image = updatedImage
- self.tintMaskIconImageView.image = updatedImage
let bottomInset: CGFloat = 0.0
- let imageFrame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) / 2.0), y: floor((size.height - image.size.height) / 2.0) - bottomInset), size: image.size)
+ var imageFrame = CGRect(origin: CGPoint(x: floor((size.width - image.size.width) / 2.0), y: floor((size.height - image.size.height) / 2.0) - bottomInset), size: image.size)
+ if case .scheduledMessages = item {
+ imageFrame.origin.y += 1.0
+ }
self.iconImageView.frame = imageFrame
- self.tintMaskIconImageView.frame = imageFrame
if let animationView = self.animationView {
let width = AccessoryItemIconButton.calculateWidth(item: item, image: image, text: "", strings: self.strings)
@@ -332,6 +322,7 @@ final class AccessoryItemIconButton: HighlightTrackingButton, GlassBackgroundVie
self.tintMask.addSubview(tintMaskAnimationView)
}
}
+ view.setMonochromaticEffect(tintColor: self.theme.chat.inputPanel.inputControlColor)
let animationFrameValue = CGRect(origin: CGPoint(x: animationFrame.minX + floor((animationFrame.width - animationSize.width) / 2.0), y: animationFrame.minY + floor((animationFrame.height - animationSize.height) / 2.0)), size: animationSize)
view.frame = animationFrameValue
if let tintMaskAnimationView = self.tintMaskAnimationView {
diff --git a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift
index 0c19ac9616..dcf2aef9bb 100644
--- a/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift
+++ b/submodules/TelegramUI/Components/Chat/ChatTextInputPanelNode/Sources/ChatTextInputPanelNode.swift
@@ -214,11 +214,9 @@ private func makeTextInputTheme(context: AccountContext, interfaceState: ChatPre
public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, ChatInputTextNodeDelegate {
public let clippingNode: ASDisplayNode
public let textPlaceholderNode: ImmediateTextNodeWithEntities
- public let tintMaskTextPlaceholderNode: ImmediateTextNodeWithEntities
public var textLockIconNode: ASImageNode?
public var contextPlaceholderNode: TextNode?
- public var tintContextPlaceholderNode: TextNode?
public var slowmodePlaceholderNode: ChatTextInputSlowmodePlaceholderNode?
public let textInputContainerBackgroundView: GlassBackgroundView
public let textInputContainer: ASDisplayNode
@@ -521,20 +519,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
self.textPlaceholderNode.contentsScale = UIScreenScale
self.textPlaceholderNode.maximumNumberOfLines = 1
self.textPlaceholderNode.isUserInteractionEnabled = false
-
- //TODO:release add tinted output instead
- self.tintMaskTextPlaceholderNode = ImmediateTextNodeWithEntities()
- self.tintMaskTextPlaceholderNode.arguments = TextNodeWithEntities.Arguments(
- context: context,
- cache: context.animationCache,
- renderer: context.animationRenderer,
- placeholderColor: .clear,
- attemptSynchronous: true
- )
- self.tintMaskTextPlaceholderNode.contentMode = .topLeft
- self.tintMaskTextPlaceholderNode.contentsScale = UIScreenScale
- self.tintMaskTextPlaceholderNode.maximumNumberOfLines = 1
-
+
self.menuButton = HighlightTrackingButtonNode()
self.menuButton.clipsToBounds = true
self.menuButton.cornerRadius = 16.0
@@ -566,7 +551,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
self.attachmentButton.isAccessibilityElement = true
self.attachmentButtonBackground = GlassBackgroundView(frame: CGRect())
- self.attachmentButtonBackground.isUserInteractionEnabled = false
self.attachmentButton.addSubview(self.attachmentButtonBackground)
self.attachmentButtonIcon = GlassBackgroundView.ContentImageView()
@@ -785,7 +769,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
self.clippingNode.addSubnode(self.textInputBackgroundNode)
self.textInputContainerBackgroundView.contentView.addSubview(self.textPlaceholderNode.view)
- self.textInputContainerBackgroundView.maskContentView.addSubview(self.tintMaskTextPlaceholderNode.view)
self.menuButton.view.addSubview(self.menuButtonBackgroundView)
self.menuButton.addSubnode(self.menuButtonClippingNode)
@@ -1039,6 +1022,8 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
}
private func calculateTextFieldMetrics(width: CGFloat, maxHeight: CGFloat, metrics: LayoutMetrics) -> (accessoryButtonsWidth: CGFloat, textFieldHeight: CGFloat, isOverflow: Bool) {
+ let maxHeight = max(maxHeight, 40.0)
+
var textFieldInsets = self.textFieldInsets(metrics: metrics)
if self.actionButtons.frame.width > 40.0 {
textFieldInsets.right = self.actionButtons.frame.width - 2.0
@@ -1076,7 +1061,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
let unboundTextFieldHeight = max(textFieldMinHeight, ceil(measuredHeight))
- let maxNumberOfLines = min(12, (Int(fieldMaxHeight - 11.0) - 33) / 22)
+ let maxNumberOfLines = max(1, min(12, (Int(fieldMaxHeight - 11.0) - 33) / 22))
let updatedMaxHeight = (CGFloat(maxNumberOfLines) * (22.0 + 2.0) + 10.0)
@@ -1256,6 +1241,8 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
) -> CGFloat {
let previousAdditionalSideInsets = self.validLayout?.4
self.validLayout = (width, leftInset, rightInset, bottomInset, additionalSideInsets, maxHeight, maxOverlayHeight, metrics, isSecondary, isMediaInputExpanded)
+
+ let placeholderColor: UIColor = interfaceState.theme.chat.inputPanel.inputPlaceholderColor
var transition = transition
var additionalOffset: CGFloat = 0.0
@@ -2423,21 +2410,16 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
if interfaceState.slowmodeState == nil || isScheduledMessages, let contextPlaceholder = interfaceState.inputTextPanelState.contextPlaceholder {
let placeholderLayout = TextNode.asyncLayout(self.contextPlaceholderNode)
- let tintPlaceholderLayout = TextNode.asyncLayout(self.tintContextPlaceholderNode)
+ let contextPlaceholder = NSMutableAttributedString(attributedString: contextPlaceholder)
+ contextPlaceholder.addAttribute(.foregroundColor, value: placeholderColor.withAlphaComponent(1.0), range: NSRange(location: 0, length: contextPlaceholder.length))
let (placeholderSize, placeholderApply) = placeholderLayout(TextNodeLayoutArguments(attributedString: contextPlaceholder, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: width - leftInset - rightInset - textFieldInsets.left - textFieldInsets.right - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right - accessoryButtonsWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let tintContextPlaceholder = NSMutableAttributedString(attributedString: contextPlaceholder)
tintContextPlaceholder.addAttribute(.foregroundColor, value: UIColor.black, range: NSRange(location: 0, length: tintContextPlaceholder.length))
- let (_, tintPlaceholderApply) = tintPlaceholderLayout(TextNodeLayoutArguments(attributedString: tintContextPlaceholder, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: width - leftInset - rightInset - textFieldInsets.left - textFieldInsets.right - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right - accessoryButtonsWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let contextPlaceholderNode = placeholderApply()
- let tintContextPlaceholderNode = tintPlaceholderApply()
if let currentContextPlaceholderNode = self.contextPlaceholderNode, currentContextPlaceholderNode !== contextPlaceholderNode {
self.contextPlaceholderNode = nil
currentContextPlaceholderNode.removeFromSupernode()
}
- if let currentTintContextPlaceholderNode = self.tintContextPlaceholderNode, currentTintContextPlaceholderNode !== tintContextPlaceholderNode {
- self.tintContextPlaceholderNode = nil
- currentTintContextPlaceholderNode.removeFromSupernode()
- }
if self.contextPlaceholderNode !== contextPlaceholderNode {
contextPlaceholderNode.displaysAsynchronously = false
@@ -2445,12 +2427,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
self.contextPlaceholderNode = contextPlaceholderNode
self.textInputContainerBackgroundView.contentView.insertSubview(contextPlaceholderNode.view, aboveSubview: self.textPlaceholderNode.view)
}
- if self.tintContextPlaceholderNode !== tintContextPlaceholderNode {
- tintContextPlaceholderNode.displaysAsynchronously = false
- tintContextPlaceholderNode.isUserInteractionEnabled = false
- self.tintContextPlaceholderNode = tintContextPlaceholderNode
- self.textInputContainerBackgroundView.maskContentView.insertSubview(tintContextPlaceholderNode.view, aboveSubview: self.tintMaskTextPlaceholderNode.view)
- }
let _ = placeholderApply()
@@ -2460,21 +2436,14 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
} else {
placeholderTransition = .immediate
}
- placeholderTransition.updateFrame(node: contextPlaceholderNode, frame: CGRect(origin: CGPoint(x: self.textInputViewInternalInsets.left, y: hideOffset.y + textFieldInsets.top + self.textInputViewInternalInsets.top + textInputViewRealInsets.top + UIScreenPixel), size: placeholderSize.size))
- contextPlaceholderNode.alpha = audioRecordingItemsAlpha
-
- placeholderTransition.updateFrame(node: tintContextPlaceholderNode, frame: CGRect(origin: CGPoint(x: self.textInputViewInternalInsets.left, y: hideOffset.y + textFieldInsets.top + self.textInputViewInternalInsets.top + textInputViewRealInsets.top + UIScreenPixel), size: placeholderSize.size))
- tintContextPlaceholderNode.alpha = audioRecordingItemsAlpha
+ placeholderTransition.updateFrame(node: contextPlaceholderNode, frame: CGRect(origin: CGPoint(x: self.textInputViewInternalInsets.left, y: hideOffset.y + textFieldInsets.top + self.textInputViewInternalInsets.top + textInputViewRealInsets.top + UIScreenPixel + (accessoryPanel != nil ? 52.0 : 0.0)), size: placeholderSize.size))
+ contextPlaceholderNode.view.setMonochromaticEffect(tintColor: placeholderColor)
+ contextPlaceholderNode.alpha = audioRecordingItemsAlpha * placeholderColor.alpha
} else {
if let contextPlaceholderNode = self.contextPlaceholderNode {
self.contextPlaceholderNode = nil
contextPlaceholderNode.removeFromSupernode()
- self.textPlaceholderNode.alpha = 1.0
- self.tintMaskTextPlaceholderNode.alpha = 1.0
- }
- if let tintContextPlaceholderNode = self.tintContextPlaceholderNode {
- self.tintContextPlaceholderNode = nil
- tintContextPlaceholderNode.removeFromSupernode()
+ self.textPlaceholderNode.alpha = 1.0 * placeholderColor.alpha
}
}
@@ -2499,11 +2468,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
if (interfaceState.slowmodeState != nil && rightSlowModeInset.isZero && !isScheduledMessages && interfaceState.editMessageState == nil) || interfaceState.inputTextPanelState.contextPlaceholder != nil {
self.textPlaceholderNode.isHidden = true
- self.tintMaskTextPlaceholderNode.isHidden = true
self.slowmodePlaceholderNode?.isHidden = inputHasText
} else {
self.textPlaceholderNode.isHidden = inputHasText
- self.tintMaskTextPlaceholderNode.isHidden = inputHasText
self.slowmodePlaceholderNode?.isHidden = true
}
@@ -2539,38 +2506,24 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
let textPlaceholderSize: CGSize
let textPlaceholderMaxWidth: CGFloat = max(1.0, nextButtonTopRight.x - 12.0)
- let placeholderColor: UIColor = interfaceState.theme.chat.inputPanel.inputPlaceholderColor
- if #available(iOS 26.0, *) {
- //placeholderColor = placeholderColor.withProminence(.tertiary)
- }
- //self.textPlaceholderNode.view.tintColor = .red
-
if (updatedPlaceholder != nil && self.currentPlaceholder != updatedPlaceholder) || themeUpdated {
let currentPlaceholder = updatedPlaceholder ?? self.currentPlaceholder ?? ""
self.currentPlaceholder = currentPlaceholder
let baseFontSize = max(minInputFontSize, interfaceState.fontSize.baseDisplaySize)
- let attributedPlaceholder = NSMutableAttributedString(string: currentPlaceholder, font: Font.regular(baseFontSize), textColor: placeholderColor)
+ let attributedPlaceholder = NSMutableAttributedString(string: currentPlaceholder, font: Font.regular(baseFontSize), textColor: placeholderColor.withAlphaComponent(1.0))
if placeholderHasStar, let range = attributedPlaceholder.string.range(of: "#") {
attributedPlaceholder.addAttribute(.attachment, value: PresentationResourcesChat.chatPlaceholderStarIcon(interfaceState.theme)!, range: NSRange(range, in: attributedPlaceholder.string))
- attributedPlaceholder.addAttribute(.foregroundColor, value: placeholderColor, range: NSRange(range, in: attributedPlaceholder.string))
+ attributedPlaceholder.addAttribute(.foregroundColor, value: placeholderColor.withAlphaComponent(1.0), range: NSRange(range, in: attributedPlaceholder.string))
attributedPlaceholder.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: attributedPlaceholder.string))
}
- let attributedTintMaskPlaceholder = NSMutableAttributedString(string: currentPlaceholder, font: Font.regular(baseFontSize), textColor: UIColor(white: 0.0, alpha: placeholderColor.alpha))
- if placeholderHasStar, let range = attributedPlaceholder.string.range(of: "#") {
- attributedTintMaskPlaceholder.addAttribute(.attachment, value: PresentationResourcesChat.chatPlaceholderStarIcon(interfaceState.theme)!, range: NSRange(range, in: attributedPlaceholder.string))
- attributedTintMaskPlaceholder.addAttribute(.foregroundColor, value: UIColor.black, range: NSRange(range, in: attributedPlaceholder.string))
- attributedTintMaskPlaceholder.addAttribute(.baselineOffset, value: 1.0, range: NSRange(range, in: attributedPlaceholder.string))
- }
-
self.textPlaceholderNode.attributedText = attributedPlaceholder
- self.tintMaskTextPlaceholderNode.attributedText = attributedTintMaskPlaceholder
+ self.textPlaceholderNode.view.setMonochromaticEffect(tintColor: placeholderColor)
self.textInputNode?.textView.accessibilityHint = currentPlaceholder
let placeholderSize = self.textPlaceholderNode.updateLayout(CGSize(width: textPlaceholderMaxWidth, height: CGFloat.greatestFiniteMagnitude))
- let _ = self.tintMaskTextPlaceholderNode.updateLayout(CGSize(width: textPlaceholderMaxWidth, height: CGFloat.greatestFiniteMagnitude))
if transition.isAnimated, let snapshotLayer = self.textPlaceholderNode.layer.snapshotContentTree() {
self.textPlaceholderNode.supernode?.layer.insertSublayer(snapshotLayer, above: self.textPlaceholderNode.layer)
@@ -2580,15 +2533,6 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
self.textPlaceholderNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.18)
}
- let _ = self.tintMaskTextPlaceholderNode.updateLayout(CGSize(width: textPlaceholderMaxWidth, height: CGFloat.greatestFiniteMagnitude))
- if transition.isAnimated, let snapshotLayer = self.tintMaskTextPlaceholderNode.layer.snapshotContentTree() {
- self.tintMaskTextPlaceholderNode.supernode?.layer.insertSublayer(snapshotLayer, above: self.tintMaskTextPlaceholderNode.layer)
- snapshotLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.22, removeOnCompletion: false, completion: { [weak snapshotLayer] _ in
- snapshotLayer?.removeFromSuperlayer()
- })
- self.tintMaskTextPlaceholderNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.18)
- }
-
textPlaceholderSize = placeholderSize
} else {
textPlaceholderSize = self.textPlaceholderNode.bounds.size
@@ -2623,13 +2567,11 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
}
}
transition.updateFrame(node: self.textPlaceholderNode, frame: textPlaceholderFrame)
- transition.updateFrame(node: self.tintMaskTextPlaceholderNode, frame: textPlaceholderFrame)
- let textPlaceholderAlpha: CGFloat = audioRecordingItemsAlpha
+ let textPlaceholderAlpha: CGFloat = audioRecordingItemsAlpha * placeholderColor.alpha
transition.updateAlpha(node: self.textPlaceholderNode, alpha: textPlaceholderAlpha)
- transition.updateAlpha(node: self.tintMaskTextPlaceholderNode, alpha: textPlaceholderAlpha)
- if let removeAccessoryButtons = removeAccessoryButtons {
+ if let removeAccessoryButtons {
for button in removeAccessoryButtons {
let buttonFrame = CGRect(origin: CGPoint(x: button.frame.origin.x + additionalOffset, y: textInputFrame.maxY - minimalInputHeight), size: button.frame.size)
transition.updateFrame(layer: button.layer, frame: buttonFrame)
@@ -2700,7 +2642,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
let attachmentButtonFrame = CGRect(origin: CGPoint(x: attachmentButtonX, y: textInputFrame.maxY - 40.0), size: CGSize(width: 40.0, height: 40.0))
self.attachmentButtonBackground.frame = CGRect(origin: CGPoint(), size: attachmentButtonFrame.size)
- self.attachmentButtonBackground.update(size: attachmentButtonFrame.size, cornerRadius: attachmentButtonFrame.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: isEditingMedia ? .init(kind: .custom, color: interfaceState.theme.chat.inputPanel.actionControlFillColor) : .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: ComponentTransition(transition))
+ self.attachmentButtonBackground.update(size: attachmentButtonFrame.size, cornerRadius: attachmentButtonFrame.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: isEditingMedia ? .init(kind: .custom, color: interfaceState.theme.chat.inputPanel.actionControlFillColor) : .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), isInteractive: true, transition: ComponentTransition(transition))
transition.updateFrame(layer: self.attachmentButton.layer, frame: attachmentButtonFrame)
transition.updateFrame(node: self.attachmentButtonDisabledNode, frame: self.attachmentButton.frame)
@@ -3667,11 +3609,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
if let interfaceState = self.presentationInterfaceState {
if (interfaceState.slowmodeState != nil && !isScheduledMessages && interfaceState.editMessageState == nil) || interfaceState.inputTextPanelState.contextPlaceholder != nil {
self.textPlaceholderNode.isHidden = true
- self.tintMaskTextPlaceholderNode.isHidden = true
self.slowmodePlaceholderNode?.isHidden = inputHasText
} else {
self.textPlaceholderNode.isHidden = inputHasText
- self.tintMaskTextPlaceholderNode.isHidden = inputHasText
self.slowmodePlaceholderNode?.isHidden = true
}
}
@@ -4721,7 +4661,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
public func frameForAccessoryButton(_ item: ChatTextInputAccessoryItem) -> CGRect? {
for (buttonItem, buttonNode) in self.accessoryItemButtons {
if buttonItem == item {
- return buttonNode.frame
+ return self.view.convert(buttonNode.bounds.insetBy(dx: 0.0, dy: 6.0), from: buttonNode)
}
}
return nil
@@ -4744,9 +4684,9 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
public func frameForInputActionButton() -> CGRect? {
if !self.actionButtons.alpha.isZero {
if self.actionButtons.micButton.alpha.isZero {
- return self.actionButtons.frame.insetBy(dx: 0.0, dy: 6.0).offsetBy(dx: 4.0, dy: 0.0)
+ return self.actionButtons.frame.insetBy(dx: 0.0, dy: -4.0).offsetBy(dx: 0.0, dy: 0.0)
} else {
- return self.actionButtons.frame.insetBy(dx: 0.0, dy: 6.0).offsetBy(dx: 2.0, dy: 0.0)
+ return self.actionButtons.frame.insetBy(dx: 0.0, dy: -4.0).offsetBy(dx: 0.0, dy: 0.0)
}
}
return nil
@@ -4755,7 +4695,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
public func frameForStickersButton() -> CGRect? {
for (item, button) in self.accessoryItemButtons {
if case let .input(_, inputMode) = item, case .stickers = inputMode {
- return button.frame.insetBy(dx: 0.0, dy: 6.0)
+ return self.view.convert(button.bounds.insetBy(dx: 0.0, dy: 6.0), from: button)
}
}
return nil
@@ -4764,7 +4704,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
public func frameForEmojiButton() -> CGRect? {
for (item, button) in self.accessoryItemButtons {
if case let .input(_, inputMode) = item, case .emoji = inputMode {
- return button.frame.insetBy(dx: 0.0, dy: 6.0)
+ return self.view.convert(button.bounds.insetBy(dx: 0.0, dy: 6.0), from: button)
}
}
return nil
@@ -4773,7 +4713,7 @@ public class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDeleg
public func frameForGiftButton() -> CGRect? {
for (item, button) in self.accessoryItemButtons {
if case .gift = item {
- return button.frame.insetBy(dx: 0.0, dy: 6.0)
+ return self.view.convert(button.bounds.insetBy(dx: 0.0, dy: 6.0), from: button)
}
}
return nil
diff --git a/submodules/TelegramUI/Components/ChatTextInputMediaRecordingButton/Sources/ChatTextInputMediaRecordingButton.swift b/submodules/TelegramUI/Components/ChatTextInputMediaRecordingButton/Sources/ChatTextInputMediaRecordingButton.swift
index 7f1ab9ea04..4587bc4a00 100644
--- a/submodules/TelegramUI/Components/ChatTextInputMediaRecordingButton/Sources/ChatTextInputMediaRecordingButton.swift
+++ b/submodules/TelegramUI/Components/ChatTextInputMediaRecordingButton/Sources/ChatTextInputMediaRecordingButton.swift
@@ -420,11 +420,12 @@ public final class ChatTextInputMediaRecordingButton: TGModernConversationInputM
animationName = "anim_micToVideo"
}
+ let animationTintColor = self.useDarkTheme ? .white : self.theme.chat.inputPanel.inputControlColor
let _ = self.animationView.update(
transition: .immediate,
component: AnyComponent(LottieComponent(
content: LottieComponent.AppBundleContent(name: animationName),
- color: self.useDarkTheme ? .white : self.theme.chat.inputPanel.inputControlColor
+ color: animationTintColor
)),
environment: {},
containerSize: animationFrame.size
@@ -437,6 +438,7 @@ public final class ChatTextInputMediaRecordingButton: TGModernConversationInputM
view.output = self.animationOutput
self.updateShadow()
}
+ view.setMonochromaticEffect(tintColor: animationTintColor)
view.frame = animationFrame
if previousMode != mode {
diff --git a/submodules/TelegramUI/Components/ChatTextInputMediaRecordingButton/Sources/LockView.swift b/submodules/TelegramUI/Components/ChatTextInputMediaRecordingButton/Sources/LockView.swift
index d2731acbe1..09731c4b75 100644
--- a/submodules/TelegramUI/Components/ChatTextInputMediaRecordingButton/Sources/LockView.swift
+++ b/submodules/TelegramUI/Components/ChatTextInputMediaRecordingButton/Sources/LockView.swift
@@ -65,22 +65,12 @@ final class LockView: UIButton, TGModernConversationInputMicButtonLock {
}
func updateTheme(_ theme: PresentationTheme) {
-// [
-// "Rectangle.Заливка 1": theme.chat.inputPanel.panelBackgroundColor,
-// "Rectangle.Rectangle.Обводка 1": theme.chat.inputPanel.panelControlAccentColor,
-// "Rectangle 2.Rectangle.Обводка 1": theme.chat.inputPanel.panelControlAccentColor,
-// "Path.Path.Обводка 1": theme.chat.inputPanel.panelControlAccentColor,
-// "Path 4.Path 4.Обводка 1": theme.chat.inputPanel.panelControlAccentColor
-// ].forEach { key, value in
-// idleView.setValueProvider(ColorValueProvider(value.lottieColorValue), keypath: AnimationKeypath(keypath: "\(key).Color"))
-// }
-//
for keypath in idleView.allKeypaths(predicate: { $0.keys.last == "Color" }) {
- idleView.setValueProvider(ColorValueProvider(theme.chat.inputPanel.panelControlAccentColor.lottieColorValue), keypath: AnimationKeypath(keypath: keypath))
+ idleView.setValueProvider(ColorValueProvider(theme.chat.inputPanel.panelControlColor.lottieColorValue), keypath: AnimationKeypath(keypath: keypath))
}
for keypath in lockingView.allKeypaths(predicate: { $0.keys.last == "Color" }) {
- lockingView.setValueProvider(ColorValueProvider(theme.chat.inputPanel.panelControlAccentColor.lottieColorValue), keypath: AnimationKeypath(keypath: keypath))
+ lockingView.setValueProvider(ColorValueProvider(theme.chat.inputPanel.panelControlColor.lottieColorValue), keypath: AnimationKeypath(keypath: keypath))
}
//
// [
diff --git a/submodules/TelegramUI/Components/GlassBackgroundComponent/Sources/GlassBackgroundComponent.swift b/submodules/TelegramUI/Components/GlassBackgroundComponent/Sources/GlassBackgroundComponent.swift
index 88d6c0083e..de07391ffc 100644
--- a/submodules/TelegramUI/Components/GlassBackgroundComponent/Sources/GlassBackgroundComponent.swift
+++ b/submodules/TelegramUI/Components/GlassBackgroundComponent/Sources/GlassBackgroundComponent.swift
@@ -202,6 +202,14 @@ public class GlassBackgroundView: UIView {
}
}
+ override public var tintColor: UIColor? {
+ didSet {
+ if self.tintColor != oldValue {
+ self.setMonochromaticEffect(tintColor: self.tintColor)
+ }
+ }
+ }
+
override public init(frame: CGRect) {
self.tintImageView = UIImageView()
@@ -252,16 +260,19 @@ public class GlassBackgroundView: UIView {
let cornerRadius: CGFloat
let isDark: Bool
let tintColor: TintColor
+ let isInteractive: Bool
- init(cornerRadius: CGFloat, isDark: Bool, tintColor: TintColor) {
+ init(cornerRadius: CGFloat, isDark: Bool, tintColor: TintColor, isInteractive: Bool) {
self.cornerRadius = cornerRadius
self.isDark = isDark
self.tintColor = tintColor
+ self.isInteractive = isInteractive
}
}
private let backgroundNode: NavigationBackgroundNode?
private let nativeView: UIVisualEffectView?
+ private let nativeContainerView: UIVisualEffectView?
private let foregroundView: UIImageView?
private let shadowView: UIImageView?
@@ -283,19 +294,23 @@ public class GlassBackgroundView: UIView {
public override init(frame: CGRect) {
if #available(iOS 26.0, *) {
self.backgroundNode = nil
- let glassEffect = UIGlassEffect(style: .clear)
+
+ let glassEffect = UIGlassEffect(style: .regular)
glassEffect.isInteractive = false
let nativeView = UIVisualEffectView(effect: glassEffect)
- nativeView.layer.cornerCurve = .circular
self.nativeView = nativeView
- nativeView.overrideUserInterfaceStyle = .light
- nativeView.traitOverrides.userInterfaceStyle = .light
- //self.foregroundView = UIImageView()
+
+ let glassContainerEffect = UIGlassContainerEffect()
+ let nativeContainerView = UIVisualEffectView(effect: glassContainerEffect)
+ self.nativeContainerView = nativeContainerView
+ nativeContainerView.contentView.addSubview(nativeView)
+
self.foregroundView = nil
- self.shadowView = UIImageView()
+ self.shadowView = nil
} else {
self.backgroundNode = NavigationBackgroundNode(color: .black, enableBlur: true, customBlurRadius: 5.0)
self.nativeView = nil
+ self.nativeContainerView = nil
self.foregroundView = UIImageView()
self.shadowView = UIImageView()
}
@@ -316,8 +331,8 @@ public class GlassBackgroundView: UIView {
if let shadowView = self.shadowView {
self.addSubview(shadowView)
}
- if let nativeView = self.nativeView {
- self.addSubview(nativeView)
+ if let nativeContainerView = self.nativeContainerView {
+ self.addSubview(nativeContainerView)
}
if let backgroundNode = self.backgroundNode {
self.addSubview(backgroundNode.view)
@@ -333,8 +348,17 @@ public class GlassBackgroundView: UIView {
fatalError("init(coder:) has not been implemented")
}
- public func update(size: CGSize, cornerRadius: CGFloat, isDark: Bool, tintColor: TintColor, transition: ComponentTransition) {
- if let nativeView = self.nativeView {
+ override public func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
+ /*if let nativeContainerView = self.nativeContainerView {
+ if let result = nativeContainerView.hitTest(self.convert(point, to: nativeContainerView), with: event) {
+ return result
+ }
+ }*/
+ return nil
+ }
+
+ public func update(size: CGSize, cornerRadius: CGFloat, isDark: Bool, tintColor: TintColor, isInteractive: Bool = false, transition: ComponentTransition) {
+ if let nativeContainerView = self.nativeContainerView, let nativeView = self.nativeView {
let previousFrame = nativeView.frame
if transition.animation.isImmediate {
@@ -347,6 +371,8 @@ public class GlassBackgroundView: UIView {
}
nativeView.layer.animateFrame(from: previousFrame, to: CGRect(origin: CGPoint(), size: size), duration: 0.4, timingFunction: kCAMediaTimingFunctionSpring)
}
+
+ transition.setFrame(view: nativeContainerView, frame: CGRect(origin: CGPoint(), size: size))
}
if let backgroundNode = self.backgroundNode {
backgroundNode.updateColor(color: .clear, forceKeepBlur: tintColor.color.alpha != 1.0, transition: transition.containedViewLayoutTransition)
@@ -356,7 +382,7 @@ public class GlassBackgroundView: UIView {
let shadowInset: CGFloat = 32.0
- let params = Params(cornerRadius: cornerRadius, isDark: isDark, tintColor: tintColor)
+ let params = Params(cornerRadius: cornerRadius, isDark: isDark, tintColor: tintColor, isInteractive: isInteractive)
if self.params != params {
self.params = params
@@ -378,18 +404,21 @@ public class GlassBackgroundView: UIView {
if let foregroundView = self.foregroundView {
foregroundView.image = GlassBackgroundView.generateLegacyGlassImage(size: CGSize(width: cornerRadius * 2.0, height: cornerRadius * 2.0), inset: shadowInset, isDark: isDark, fillColor: tintColor.color)
} else {
- if let nativeView {
+ if let nativeContainerView = self.nativeContainerView, let nativeView {
if #available(iOS 26.0, *) {
- let glassEffect = UIGlassEffect(style: .clear)
+ let glassEffect = UIGlassEffect(style: .regular)
switch tintColor.kind {
case .panel:
- glassEffect.tintColor = tintColor.color.withMultipliedAlpha(1.2)
+ glassEffect.tintColor = nil
case .custom:
glassEffect.tintColor = tintColor.color
}
- glassEffect.isInteractive = false
+ glassEffect.isInteractive = params.isInteractive
nativeView.effect = glassEffect
+ let _ = nativeContainerView
+ //nativeContainerView.overrideUserInterfaceStyle = .light// isDark ? .dark : .light
+ self.overrideUserInterfaceStyle = isDark ? .dark : .light
}
}
}
@@ -407,6 +436,27 @@ public class GlassBackgroundView: UIView {
}
}
+public final class GlassBackgroundContainerView: UIView {
+ private final class ContentView: UIView {
+
+ }
+
+ private let contentViewImpl: ContentView
+ public var contentView: UIView {
+ return self.contentViewImpl
+ }
+
+ public override init(frame: CGRect) {
+ self.contentViewImpl = ContentView()
+
+ super.init(frame: frame)
+ }
+
+ required public init?(coder: NSCoder) {
+ fatalError("init(coder:) has not been implemented")
+ }
+}
+
public final class VariableBlurView: UIVisualEffectView {
public let maxBlurRadius: CGFloat
@@ -536,8 +586,7 @@ public extension GlassBackgroundView {
return result
}
- // Your requested closure:
- let addShadow: (Bool, CGPoint, CGFloat, CGFloat, UIColor) -> Void = { isOuter, position, blur, spread, shadowColor in
+ let addShadow: (Bool, CGPoint, CGFloat, CGFloat, UIColor, Bool) -> Void = { isOuter, position, blur, spread, shadowColor, isMultiply in
var blur = blur
blur += abs(spread)
@@ -571,132 +620,70 @@ public extension GlassBackgroundView {
context.fillPath()
context.setBlendMode(.normal)
} else {
- context.beginTransparencyLayer(auxiliaryInfo: nil)
- context.saveGState()
- defer {
- context.restoreGState()
- context.endTransparencyLayer()
+ if let image = generateImage(size, rotatedContext: { size, context in
+ context.clear(CGRect(origin: CGPoint(), size: size))
+ let spreadRect = CGRect(origin: CGPoint(x: inset, y: inset), size: innerSize).insetBy(dx: -0.25, dy: -0.25)
+ let spreadPath = UIBezierPath(
+ roundedRect: spreadRect,
+ cornerRadius: min(spreadRect.width, spreadRect.height) * 0.5
+ ).cgPath
+
+ context.setShadow(offset: CGSize(width: position.x, height: position.y), blur: blur, color: shadowColor.cgColor)
+ context.setFillColor(UIColor.black.withAlphaComponent(1.0).cgColor)
+ let enclosingRect = spreadRect.insetBy(dx: -10000.0, dy: -10000.0)
+ context.addPath(UIBezierPath(rect: enclosingRect).cgPath)
+ context.addPath(spreadPath)
+ context.fillPath(using: .evenOdd)
+
+ let cleanRect = CGRect(origin: CGPoint(x: inset, y: inset), size: innerSize)
+ let cleanPath = UIBezierPath(
+ roundedRect: cleanRect,
+ cornerRadius: min(cleanRect.width, cleanRect.height) * 0.5
+ ).cgPath
+ context.setBlendMode(.copy)
+ context.setFillColor(UIColor.clear.cgColor)
+ context.addPath(UIBezierPath(rect: enclosingRect).cgPath)
+ context.addPath(cleanPath)
+ context.fillPath(using: .evenOdd)
+ context.setBlendMode(.normal)
+ }) {
+ UIGraphicsPushContext(context)
+ image.draw(in: CGRect(origin: .zero, size: size), blendMode: isMultiply ? .destinationOut : .normal, alpha: 1.0)
+ UIGraphicsPopContext()
}
-
- let spreadRect = CGRect(origin: CGPoint(x: inset, y: inset), size: innerSize).insetBy(dx: -0.25, dy: -0.25)
- let spreadPath = UIBezierPath(
- roundedRect: spreadRect,
- cornerRadius: min(spreadRect.width, spreadRect.height) * 0.5
- ).cgPath
-
- context.setShadow(offset: CGSize(width: position.x, height: position.y), blur: blur, color: shadowColor.cgColor)
- context.setFillColor(UIColor.black.withAlphaComponent(1.0).cgColor)
- let enclosingRect = spreadRect.insetBy(dx: -10000.0, dy: -10000.0)
- context.addPath(UIBezierPath(rect: enclosingRect).cgPath)
- context.addPath(spreadPath)
- context.fillPath(using: .evenOdd)
-
- let cleanRect = CGRect(origin: CGPoint(x: inset, y: inset), size: innerSize)
- let cleanPath = UIBezierPath(
- roundedRect: cleanRect,
- cornerRadius: min(cleanRect.width, cleanRect.height) * 0.5
- ).cgPath
- context.setBlendMode(.copy)
- context.setFillColor(UIColor.clear.cgColor)
- context.addPath(UIBezierPath(rect: enclosingRect).cgPath)
- context.addPath(cleanPath)
- context.fillPath(using: .evenOdd)
- context.setBlendMode(.normal)
}
}
if isDark {
- addShadow(true, CGPoint(), 16.0, 0.0, UIColor(white: 0.0, alpha: 0.12))
- addShadow(true, CGPoint(), 8.0, 0.0, UIColor(white: 0.0, alpha: 0.1))
+ addShadow(true, CGPoint(), 16.0, 0.0, UIColor(white: 0.0, alpha: 0.12), false)
+ addShadow(true, CGPoint(), 8.0, 0.0, UIColor(white: 0.0, alpha: 0.1), false)
context.setFillColor(fillColor.cgColor)
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset))
- addShadow(false, CGPoint(x: 0.0, y: 0.0), 3.0, 0.0, UIColor(white: 1.0, alpha: 0.5))
- addShadow(false, CGPoint(x: 3.0, y: -3.0), 2.0, 0.0, UIColor(white: 1.0, alpha: 0.25))
- addShadow(false, CGPoint(x: -3.0, y: 3.0), 2.0, 0.0, UIColor(white: 1.0, alpha: 0.25))
+ addShadow(false, CGPoint(x: 0.0, y: 0.0), 3.0, 0.0, UIColor(white: 1.0, alpha: 0.5), false)
+ addShadow(false, CGPoint(x: 3.0, y: -3.0), 2.0, 0.0, UIColor(white: 1.0, alpha: 0.25), false)
+ addShadow(false, CGPoint(x: -3.0, y: 3.0), 2.0, 0.0, UIColor(white: 1.0, alpha: 0.25), false)
} else {
- addShadow(true, CGPoint(), 16.0, 0.0, UIColor(white: 0.0, alpha: 0.08))
- addShadow(true, CGPoint(), 8.0, 0.0, UIColor(white: 0.0, alpha: 0.08))
+ addShadow(true, CGPoint(), 32.0, 0.0, UIColor(white: 0.0, alpha: 0.08), false)
+ addShadow(true, CGPoint(), 16.0, 0.0, UIColor(white: 0.0, alpha: 0.08), false)
context.setFillColor(fillColor.cgColor)
context.fillEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: inset, dy: inset))
- addShadow(false, CGPoint(x: 3.0, y: -3.0), 0.5, 0.0, fillColor.withMultiplied(hue: 1.0, saturation: 2.0, brightness: 1.0).adjustedPerceivedBrightness(3.0).withMultipliedAlpha(1.0))
- addShadow(false, CGPoint(x: -2.0, y: 2.0), 0.5, 0.0, UIColor.black.withMultipliedAlpha(0.15))
- }
-
- if "".isEmpty {
- return
- }
-
- let maxColor = UIColor(white: 1.0, alpha: isDark ? 0.25 : 0.9)
- let minColor = UIColor(white: 1.0, alpha: 0.0)
-
- context.setFillColor(fillColor.cgColor)
- context.fillEllipse(in: CGRect(origin: CGPoint(), size: size))
-
- let lineWidth: CGFloat = isDark ? 0.66 : 0.66
-
- context.saveGState()
-
- let darkShadeColor = UIColor(white: isDark ? 1.0 : 0.0, alpha: 0.035)
- let lightShadeColor = UIColor(white: isDark ? 0.0 : 1.0, alpha: 0.035)
- let innerShadowBlur: CGFloat = 24.0
-
- context.resetClip()
- context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
- context.clip()
- context.addRect(CGRect(origin: CGPoint(), size: size).insetBy(dx: -100.0, dy: -100.0))
- context.addEllipse(in: CGRect(origin: CGPoint(), size: size))
- context.setFillColor(UIColor.black.cgColor)
- context.setShadow(offset: CGSize(width: 10.0, height: -10.0), blur: innerShadowBlur, color: darkShadeColor.cgColor)
- context.fillPath(using: .evenOdd)
-
- context.resetClip()
- context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
- context.clip()
- context.addRect(CGRect(origin: CGPoint(), size: size).insetBy(dx: -100.0, dy: -100.0))
- context.addEllipse(in: CGRect(origin: CGPoint(), size: size))
- context.setFillColor(UIColor.black.cgColor)
- context.setShadow(offset: CGSize(width: -10.0, height: 10.0), blur: innerShadowBlur, color: lightShadeColor.cgColor)
- context.fillPath(using: .evenOdd)
-
- context.restoreGState()
-
- context.setLineWidth(lineWidth)
-
- context.addRect(CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: size.width * 0.5, height: size.height)))
- context.clip()
- context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
- context.replacePathWithStrokedPath()
- context.clip()
-
- do {
- var locations: [CGFloat] = [0.0, 0.5, 0.5 + 0.2, 1.0 - 0.1, 1.0]
- let colors: [CGColor] = [maxColor.cgColor, maxColor.cgColor, minColor.cgColor, minColor.cgColor, maxColor.cgColor]
+ let highlightColor: UIColor
+ if fillColor.hsb.s > 0.5 {
+ highlightColor = fillColor.withMultiplied(hue: 1.0, saturation: 2.0, brightness: 1.0).adjustedPerceivedBrightness(2.0)
+
+ let shadowColor = fillColor.withMultiplied(hue: 1.0, saturation: 2.0, brightness: 1.0).adjustedPerceivedBrightness(0.5).withMultipliedAlpha(0.2)
+ addShadow(false, CGPoint(x: -2.0, y: 2.0), 0.5, 0.0, shadowColor, false)
+ } else {
+ highlightColor = UIColor(white: 1.0, alpha: 0.4)
+ addShadow(false, CGPoint(x: -2.0, y: 2.0), 0.5, 0.0, UIColor.black.withMultipliedAlpha(0.15), true)
+ addShadow(false, CGPoint(x: -2.0, y: 2.0), 0.6, 0.0, UIColor(white: 0.0, alpha: 0.1), false)
+ }
- let colorSpace = CGColorSpaceCreateDeviceRGB()
- let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
-
- context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
- }
-
- context.resetClip()
- context.addRect(CGRect(origin: CGPoint(x: size.width - size.width * 0.5, y: 0.0), size: CGSize(width: size.width * 0.5, height: size.height)))
- context.clip()
- context.addEllipse(in: CGRect(origin: CGPoint(), size: size).insetBy(dx: lineWidth * 0.5, dy: lineWidth * 0.5))
- context.replacePathWithStrokedPath()
- context.clip()
-
- do {
- var locations: [CGFloat] = [0.0, 0.1, 0.5 - 0.2, 0.5, 1.0]
- let colors: [CGColor] = [maxColor.cgColor, minColor.cgColor, minColor.cgColor, maxColor.cgColor, maxColor.cgColor]
-
- let colorSpace = CGColorSpaceCreateDeviceRGB()
- let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
-
- context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
+ addShadow(false, CGPoint(x: 2.0, y: -2.0), 0.5, 0.0, highlightColor, false)
}
})!.stretchableImage(withLeftCapWidth: Int(size.width * 0.5), topCapHeight: Int(size.height * 0.5))
}
@@ -784,10 +771,12 @@ public extension GlassBackgroundView {
public final class GlassBackgroundComponent: Component {
private let size: CGSize
+ private let isDark: Bool
private let tintColor: GlassBackgroundView.TintColor
- public init(size: CGSize, tintColor: GlassBackgroundView.TintColor) {
+ public init(size: CGSize, isDark: Bool, tintColor: GlassBackgroundView.TintColor) {
self.size = size
+ self.isDark = isDark
self.tintColor = tintColor
}
@@ -795,6 +784,9 @@ public final class GlassBackgroundComponent: Component {
if lhs.size != rhs.size {
return false
}
+ if lhs.isDark != rhs.isDark {
+ return false
+ }
if lhs.tintColor != rhs.tintColor {
return false
}
@@ -803,7 +795,7 @@ public final class GlassBackgroundComponent: Component {
public final class View: GlassBackgroundView {
func update(component: GlassBackgroundComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment, transition: ComponentTransition) -> CGSize {
- self.update(size: component.size, cornerRadius: component.size.height / 2.0, isDark: true, tintColor: component.tintColor, transition: transition)
+ self.update(size: component.size, cornerRadius: component.size.height / 2.0, isDark: component.isDark, tintColor: component.tintColor, transition: transition)
self.frame = CGRect(origin: .zero, size: component.size)
return component.size
diff --git a/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift b/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift
index 22f05322f5..05314e4fd4 100644
--- a/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift
+++ b/submodules/TelegramUI/Components/TabBarComponent/Sources/TabBarComponent.swift
@@ -315,6 +315,8 @@ public final class TabBarComponent: Component {
self.component = component
self.state = state
+ self.overrideUserInterfaceStyle = component.theme.overallDarkAppearance ? .dark : .light
+
if let nativeTabBar = self.nativeTabBar {
if nativeTabBar.items?.count != component.items.count {
nativeTabBar.items = (0 ..< component.items.count).map { i in
diff --git a/submodules/TelegramUI/Components/VideoMessageCameraScreen/Sources/VideoMessageCameraScreen.swift b/submodules/TelegramUI/Components/VideoMessageCameraScreen/Sources/VideoMessageCameraScreen.swift
index 21d99066ef..f6c371dee2 100644
--- a/submodules/TelegramUI/Components/VideoMessageCameraScreen/Sources/VideoMessageCameraScreen.swift
+++ b/submodules/TelegramUI/Components/VideoMessageCameraScreen/Sources/VideoMessageCameraScreen.swift
@@ -191,7 +191,6 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent {
enum ImageKey: Hashable {
case flip
case flash
- case buttonBackground
case flashImage
}
private var cachedImages: [ImageKey: UIImage] = [:]
@@ -205,9 +204,6 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent {
image = UIImage(bundleImageName: "Camera/VideoMessageFlip")!.withRenderingMode(.alwaysTemplate)
case .flash:
image = UIImage(bundleImageName: "Camera/VideoMessageFlash")!.withRenderingMode(.alwaysTemplate)
- case .buttonBackground:
- let innerSize = CGSize(width: 40.0, height: 40.0)
- image = generateFilledCircleImage(diameter: innerSize.width, color: theme.rootController.navigationBar.opaqueBackgroundColor, strokeColor: theme.chat.inputPanel.panelSeparatorColor, strokeWidth: 0.5, backgroundColor: nil)!
case .flashImage:
image = generateImage(CGSize(width: 393.0, height: 852.0), rotatedContext: { size, context in
context.clear(CGRect(origin: .zero, size: size))
@@ -590,6 +586,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent {
let flipButtonBackground = flipButtonBackground.update(
component: GlassBackgroundComponent(
size: CGSize(width: 40.0, height: 40.0),
+ isDark: environment.theme.overallDarkAppearance,
tintColor: .init(kind: .panel, color: environment.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7))
),
availableSize: CGSize(width: 40.0, height: 40.0),
@@ -691,6 +688,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent {
let flashButtonBackground = flashButtonBackground.update(
component: GlassBackgroundComponent(
size: CGSize(width: 40.0, height: 40.0),
+ isDark: environment.theme.overallDarkAppearance,
tintColor: .init(kind: .panel, color: environment.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7))
),
availableSize: CGSize(width: 40.0, height: 40.0),
@@ -719,9 +717,10 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent {
AnyComponentWithIdentity(
id: "background",
component: AnyComponent(
- Image(
- image: state.image(.buttonBackground, theme: environment.theme),
- size: CGSize(width: 40.0, height: 40.0)
+ GlassBackgroundComponent(
+ size: CGSize(width: 40.0, height: 40.0),
+ isDark: environment.theme.overallDarkAppearance,
+ tintColor: .init(kind: .panel, color: environment.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7))
)
)
),
@@ -749,7 +748,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent {
transition: context.transition
)
context.add(viewOnceButton
- .position(CGPoint(x: availableSize.width - viewOnceButton.size.width / 2.0 - 2.0 - UIScreenPixel, y: availableSize.height - viewOnceButton.size.height / 2.0 - 8.0 - viewOnceOffset))
+ .position(CGPoint(x: availableSize.width - viewOnceButton.size.width / 2.0 - 8.0, y: availableSize.height - viewOnceButton.size.height / 2.0 - 8.0 - viewOnceOffset))
.appear(.default(scale: true, alpha: true))
.disappear(.default(scale: true, alpha: true))
)
@@ -764,6 +763,7 @@ private final class VideoMessageCameraScreenComponent: CombinedComponent {
id: "background",
component: AnyComponent(GlassBackgroundComponent(
size: CGSize(width: 40.0, height: 40.0),
+ isDark: environment.theme.overallDarkAppearance,
tintColor: .init(kind: .panel, color: environment.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7))
))
),
@@ -1466,7 +1466,7 @@ public class VideoMessageCameraScreen: ViewController {
var backgroundFrame = CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: controller.inputPanelFrame.0.minY))
let actualBackgroundFrame = CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: layout.size.height))
if backgroundFrame.maxY < layout.size.height - 100.0 && (layout.inputHeight ?? 0.0).isZero && !controller.inputPanelFrame.1 && layout.additionalInsets.bottom.isZero {
- backgroundFrame = CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: layout.size.height - layout.intrinsicInsets.bottom - controller.inputPanelFrame.0.height))
+ backgroundFrame = CGRect(origin: .zero, size: CGSize(width: layout.size.width, height: layout.size.height - layout.intrinsicInsets.bottom - controller.inputPanelFrame.0.height - 8.0))
}
transition.setPosition(view: self.backgroundView, position: actualBackgroundFrame.center)
diff --git a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenMessageContextMenu.swift b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenMessageContextMenu.swift
index 41d40bcaea..da9d2e03f9 100644
--- a/submodules/TelegramUI/Sources/Chat/ChatControllerOpenMessageContextMenu.swift
+++ b/submodules/TelegramUI/Sources/Chat/ChatControllerOpenMessageContextMenu.swift
@@ -330,12 +330,6 @@ extension ChatControllerImpl {
self?.canReadHistory.set(true)
}
controller.immediateItemsTransitionAnimation = disableTransitionAnimations
- controller.getOverlayViews = { [weak self] in
- guard let self else {
- return []
- }
- return [self.chatDisplayNode.navigateButtons.view]
- }
self.currentContextController = controller
controller.premiumReactionsSelected = { [weak self, weak controller] in
diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift
index d929b56901..61b7e8aef1 100644
--- a/submodules/TelegramUI/Sources/ChatControllerNode.swift
+++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift
@@ -1311,6 +1311,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
previousInputPanelOrigin.y -= inputPanelNode.bounds.size.height
}
if let secondaryInputPanelNode = self.secondaryInputPanelNode {
+ previousInputPanelOrigin.y -= 8.0
previousInputPanelOrigin.y -= secondaryInputPanelNode.bounds.size.height
}
self.containerLayoutAndNavigationBarHeight = (layout, navigationBarHeight)
@@ -1568,6 +1569,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
inputPanelNodeBaseHeight += inputPanelNode.minimalHeight(interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics)
}
if let secondaryInputPanelNode = self.secondaryInputPanelNode {
+ inputPanelNodeBaseHeight += 8.0
inputPanelNodeBaseHeight += secondaryInputPanelNode.minimalHeight(interfaceState: self.chatPresentationInterfaceState, metrics: layout.metrics)
}
@@ -1739,6 +1741,7 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
}
}
if let secondaryInputPanelSize = secondaryInputPanelSize {
+ maximumInputNodeHeight -= 8.0
maximumInputNodeHeight -= secondaryInputPanelSize.height
}
if let accessoryPanelSize = accessoryPanelSize {
@@ -2128,8 +2131,11 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
if overlayContextPanelNode !== self.overlayContextPanelNode {
dismissedOverlayContextPanelNode = self.overlayContextPanelNode
self.overlayContextPanelNode = overlayContextPanelNode
-
- self.contentContainerNode.contentNode.addSubnode(overlayContextPanelNode)
+ if let navigationBar = self.navigationBar {
+ self.contentContainerNode.contentNode.insertSubnode(overlayContextPanelNode, belowSubnode: navigationBar)
+ } else {
+ self.contentContainerNode.contentNode.addSubnode(overlayContextPanelNode)
+ }
immediatelyLayoutOverlayContextPanelAndAnimateAppearance = true
}
} else if let overlayContextPanelNode = self.overlayContextPanelNode {
@@ -2147,10 +2153,10 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
var inputPanelHideOffset: CGFloat = 0.0
if let inputNode = self.inputNode, inputNode.hideInput {
if let inputPanelSize = inputPanelSize {
- inputPanelHideOffset += -inputPanelSize.height
+ inputPanelHideOffset += -inputPanelSize.height - 80.0
}
if let accessoryPanelSize = accessoryPanelSize {
- inputPanelHideOffset += -accessoryPanelSize.height
+ inputPanelHideOffset += -accessoryPanelSize.height - 80.0
}
}
@@ -2164,11 +2170,11 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
}
if self.secondaryInputPanelNode != nil {
- secondaryInputPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - bottomOverflowOffset - inputPanelsHeight - secondaryInputPanelSize!.height), size: CGSize(width: layout.size.width, height: secondaryInputPanelSize!.height))
+ secondaryInputPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - insets.bottom - bottomOverflowOffset - inputPanelsHeight - secondaryInputPanelSize!.height - 8.0), size: CGSize(width: layout.size.width, height: secondaryInputPanelSize!.height))
if self.dismissedAsOverlay {
secondaryInputPanelFrame!.origin.y = layout.size.height
}
- inputPanelsHeight += secondaryInputPanelSize!.height
+ inputPanelsHeight += 8.0 + secondaryInputPanelSize!.height
}
var accessoryPanelFrame: CGRect?
diff --git a/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift
index 3018633377..d889eeaa7c 100644
--- a/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift
+++ b/submodules/TelegramUI/Sources/ChatRestrictedInputPanelNode.swift
@@ -161,6 +161,7 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
let subtitleSize = self.subtitleNode.updateLayout(CGSize(width: width - leftInset - rightInset - 8.0 * 2.0, height: panelHeight))
var originX: CGFloat = leftInset + floor((width - leftInset - rightInset - textSize.width) / 2.0)
+ var totalWidth = textSize.width
if let iconImage {
let iconView: UIImageView
@@ -173,7 +174,7 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
}
iconView.image = iconImage
- let totalWidth = textSize.width + iconImage.size.width + iconSpacing
+ totalWidth += iconImage.size.width + iconSpacing
iconView.frame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - rightInset - totalWidth) / 2.0), y: floor((panelHeight - textSize.height) / 2.0) + UIScreenPixel + floorToScreenPixels((textSize.height - iconImage.size.height) / 2.0)), size: iconImage.size)
originX += iconImage.size.width + iconSpacing
@@ -190,7 +191,11 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
let subtitleFrame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - rightInset - subtitleSize.width) / 2.0), y: floor((panelHeight + combinedHeight) / 2.0) - subtitleSize.height), size: subtitleSize)
- var combinedFrame = textFrame.union(subtitleFrame).insetBy(dx: -12.0, dy: -6.0)
+ var combinedFrame = textFrame.union(subtitleFrame)
+ if let iconView {
+ combinedFrame = combinedFrame.union(iconView.frame)
+ }
+ combinedFrame = combinedFrame.insetBy(dx: -12.0, dy: -6.0)
combinedFrame.origin.y += 1.0
self.textNode.frame = textFrame.offsetBy(dx: -combinedFrame.minX, dy: -combinedFrame.minY)
diff --git a/submodules/TelegramUI/Sources/CommandChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/CommandChatInputContextPanelNode.swift
index 465a52d442..1d184dea2a 100644
--- a/submodules/TelegramUI/Sources/CommandChatInputContextPanelNode.swift
+++ b/submodules/TelegramUI/Sources/CommandChatInputContextPanelNode.swift
@@ -243,7 +243,8 @@ private struct CommandChatInputContextPanelEntry: Comparable, Identifiable {
messageCount: shortcut.totalCount,
hideSeparator: false,
hideDate: true,
- hidePeerStatus: true
+ hidePeerStatus: true,
+ isInTransparentContainer: true
)
)),
editing: false,
diff --git a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift
index c8b33b8ff2..369f90ac19 100644
--- a/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift
+++ b/submodules/TelegramUI/Sources/HorizontalListContextResultsChatInputContextPanelNode.swift
@@ -84,7 +84,6 @@ private func preparedTransition(from fromEntries: [HorizontalListContextResultsC
final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputContextPanelNode {
private let listView: ListView
- private let separatorNode: ASDisplayNode
private var currentExternalResults: ChatContextResultCollection?
private var currentProcessedResults: ChatContextResultCollection?
private var currentEntries: [HorizontalListContextResultsChatInputContextPanelEntry]?
@@ -97,11 +96,6 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
private let batchVideoContext: QueueLocalObject
override init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, fontSize: PresentationFontSize, chatPresentationContext: ChatPresentationContext) {
- self.separatorNode = ASDisplayNode()
- self.separatorNode.isLayerBacked = true
- self.separatorNode.backgroundColor = theme.list.itemPlainSeparatorColor
- self.separatorNode.isHidden = true
-
self.listView = ListView()
self.listView.isOpaque = true
self.listView.backgroundColor = theme.list.plainBackgroundColor
@@ -121,7 +115,6 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
self.clipsToBounds = true
self.addSubnode(self.listView)
- self.addSubnode(self.separatorNode)
self.listView.displayedItemRangeChanged = { [weak self] displayedRange, opaqueTransactionState in
if let strongSelf = self, let state = opaqueTransactionState as? HorizontalListContextResultsOpaqueState {
@@ -358,18 +351,10 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
self.listView.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, updateSizeAndInsets: nil, updateOpaqueState: HorizontalListContextResultsOpaqueState(entryCount: transition.entryCount, hasMore: transition.hasMore), completion: { [weak self] _ in
if let strongSelf = self, firstTime {
- let position = strongSelf.listView.position
- let separatorPosition = strongSelf.separatorNode.layer.position
-
strongSelf.listView.isHidden = false
- strongSelf.separatorNode.isHidden = false
- strongSelf.listView.position = CGPoint(x: position.x, y: position.y + strongSelf.listView.bounds.size.width)
- strongSelf.separatorNode.position = CGPoint(x: separatorPosition.x, y: separatorPosition.y + strongSelf.listView.bounds.size.width)
- ContainedViewLayoutTransition.animated(duration: 0.3, curve: .spring).animateView {
- strongSelf.listView.position = position
- strongSelf.separatorNode.position = separatorPosition
- }
+ strongSelf.layer.allowsGroupOpacity = true
+ strongSelf.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
}
})
}
@@ -378,7 +363,6 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
override func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState) {
let listHeight: CGFloat = 105.0
- transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: size.height - bottomInset - 8.0 - listHeight), size: CGSize(width: size.width, height: UIScreenPixel)))
self.listView.bounds = CGRect(x: 0.0, y: 0.0, width: listHeight, height: size.width)
//transition.updateFrame(node: self.listView, frame: CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height))
@@ -403,18 +387,18 @@ final class HorizontalListContextResultsChatInputContextPanelNode: ChatInputCont
if self.theme !== interfaceState.theme {
self.theme = interfaceState.theme
- self.separatorNode.backgroundColor = theme.list.itemPlainSeparatorColor
- self.listView.backgroundColor = theme.list.plainBackgroundColor
+ self.listView.backgroundColor = self.theme.list.plainBackgroundColor
}
}
override func animateOut(completion: @escaping () -> Void) {
- let position = self.listView.layer.position
+ /*let position = self.listView.layer.position
self.listView.layer.animatePosition(from: position, to: CGPoint(x: position.x, y: position.y + self.listView.bounds.size.width), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { _ in
completion()
+ })*/
+ self.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { _ in
+ completion()
})
- let separatorPosition = self.separatorNode.layer.position
- self.separatorNode.layer.animatePosition(from: separatorPosition, to: CGPoint(x: separatorPosition.x, y: separatorPosition.y + listView.bounds.size.width), duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false)
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
diff --git a/submodules/TelegramUI/Sources/SecretChatHandshakeStatusInputPanelNode.swift b/submodules/TelegramUI/Sources/SecretChatHandshakeStatusInputPanelNode.swift
index ad862f9774..bfb93e523b 100644
--- a/submodules/TelegramUI/Sources/SecretChatHandshakeStatusInputPanelNode.swift
+++ b/submodules/TelegramUI/Sources/SecretChatHandshakeStatusInputPanelNode.swift
@@ -8,8 +8,13 @@ import SwiftSignalKit
import LocalizedPeerData
import ChatPresentationInterfaceState
import ChatInputPanelNode
+import ComponentFlow
+import MultilineTextComponent
+import GlassBackgroundComponent
final class SecretChatHandshakeStatusInputPanelNode: ChatInputPanelNode {
+ private let titleBackground: GlassBackgroundView
+ private let title = ComponentView()
private let button: HighlightableButtonNode
private var statusDisposable: Disposable?
@@ -22,9 +27,12 @@ final class SecretChatHandshakeStatusInputPanelNode: ChatInputPanelNode {
self.button.titleNode.maximumNumberOfLines = 2
self.button.titleNode.truncationMode = .byTruncatingMiddle
+ self.titleBackground = GlassBackgroundView()
+
super.init()
self.addSubnode(self.button)
+ self.button.view.addSubview(self.titleBackground)
self.button.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: [.touchUpInside])
}
@@ -46,31 +54,48 @@ final class SecretChatHandshakeStatusInputPanelNode: ChatInputPanelNode {
}
override func updateLayout(width: CGFloat, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, additionalSideInsets: UIEdgeInsets, maxHeight: CGFloat, maxOverlayHeight: CGFloat, isSecondary: Bool, transition: ContainedViewLayoutTransition, interfaceState: ChatPresentationInterfaceState, metrics: LayoutMetrics, isMediaInputExpanded: Bool) -> CGFloat {
- if self.presentationInterfaceState != interfaceState {
- self.presentationInterfaceState = interfaceState
-
- if let renderedPeer = interfaceState.renderedPeer, let peer = renderedPeer.peer as? TelegramSecretChat, let userPeer = renderedPeer.peers[peer.regularPeerId] {
- switch peer.embeddedState {
- case .handshake:
- let text: String
- switch peer.role {
- case .creator:
- text = interfaceState.strings.DialogList_AwaitingEncryption(EnginePeer(userPeer).compactDisplayTitle).string
- case .participant:
- text = interfaceState.strings.Conversation_EncryptionProcessing
- }
- self.button.setAttributedTitle(NSAttributedString(string: text, font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.primaryTextColor, paragraphAlignment: .center), for: [])
- case .active, .terminated:
- break
+ self.presentationInterfaceState = interfaceState
+
+ var text: String?
+
+ if let renderedPeer = interfaceState.renderedPeer, let peer = renderedPeer.peer as? TelegramSecretChat, let userPeer = renderedPeer.peers[peer.regularPeerId] {
+ switch peer.embeddedState {
+ case .handshake:
+ switch peer.role {
+ case .creator:
+ text = interfaceState.strings.DialogList_AwaitingEncryption(EnginePeer(userPeer).compactDisplayTitle).string
+ case .participant:
+ text = interfaceState.strings.Conversation_EncryptionProcessing
}
+ case .active, .terminated:
+ break
}
}
- let buttonSize = self.button.measure(CGSize(width: width - 10.0, height: 100.0))
+ let titleSize = self.title.update(
+ transition: .immediate,
+ component: AnyComponent(MultilineTextComponent(
+ text: .plain(NSAttributedString(string: text ?? " ", font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.primaryTextColor, paragraphAlignment: .center))
+ )),
+ environment: {},
+ containerSize: CGSize(width: width - 16.0 * 2.0, height: 100.0)
+ )
let panelHeight = defaultHeight(metrics: metrics)
- self.button.frame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - rightInset - buttonSize.width) / 2.0), y: floor((panelHeight - buttonSize.height) / 2.0)), size: buttonSize)
+ let backgroundSize = CGSize(width: titleSize.width + 16.0 * 2.0, height: 40.0)
+ let backgroundFrame = CGRect(origin: CGPoint(x: leftInset + floor((width - leftInset - rightInset - backgroundSize.width) * 0.5), y: floor((panelHeight - backgroundSize.height) / 2.0)), size: backgroundSize)
+ transition.updateFrame(node: self.button, frame: backgroundFrame)
+ transition.updateFrame(view: self.titleBackground, frame: CGRect(origin: CGPoint(), size: backgroundFrame.size))
+ self.titleBackground.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.height * 0.5, isDark: interfaceState.theme.overallDarkAppearance, tintColor: .init(kind: .panel, color: interfaceState.theme.chat.inputPanel.inputBackgroundColor.withMultipliedAlpha(0.7)), transition: .immediate)
+ let titleFrame = CGRect(origin: CGPoint(x: floor((backgroundFrame.width - titleSize.width) * 0.5), y: floor((backgroundFrame.height - titleSize.height) * 0.5)), size: titleSize)
+ if let titleView = self.title.view {
+ if titleView.superview == nil {
+ titleView.setMonochromaticEffect(tintColor: interfaceState.theme.chat.inputPanel.primaryTextColor)
+ self.titleBackground.contentView.addSubview(titleView)
+ }
+ titleView.frame = titleFrame
+ }
return panelHeight
}
diff --git a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelButtonItem.swift b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelButtonItem.swift
index 4344efb867..806397d5dc 100644
--- a/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelButtonItem.swift
+++ b/submodules/TelegramUI/Sources/VerticalListContextResultsChatInputPanelButtonItem.swift
@@ -84,17 +84,13 @@ final class VerticalListContextResultsChatInputPanelButtonItemNode: ListViewItem
private let buttonNode: HighlightTrackingButtonNode
private let titleNode: TextNode
- private let topSeparatorNode: ASDisplayNode
private let separatorNode: ASDisplayNode
private var item: VerticalListContextResultsChatInputPanelButtonItem?
init() {
self.buttonNode = HighlightTrackingButtonNode()
-
- self.topSeparatorNode = ASDisplayNode()
- self.topSeparatorNode.isLayerBacked = true
-
+
self.separatorNode = ASDisplayNode()
self.separatorNode.isLayerBacked = true
@@ -102,7 +98,6 @@ final class VerticalListContextResultsChatInputPanelButtonItemNode: ListViewItem
super.init(layerBacked: false, dynamicBounce: false)
- self.addSubnode(self.topSeparatorNode)
self.addSubnode(self.separatorNode)
self.addSubnode(self.titleNode)
@@ -145,7 +140,7 @@ final class VerticalListContextResultsChatInputPanelButtonItemNode: ListViewItem
titleFont = Font.regular(17.0)
}
- let titleString = NSAttributedString(string: item.title, font: titleFont, textColor: item.theme.list.itemAccentColor)
+ let titleString = NSAttributedString(string: item.title, font: titleFont, textColor: item.theme.chat.inputPanel.panelControlColor)
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - params.leftInset - params.rightInset - 16.0, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
@@ -156,7 +151,6 @@ final class VerticalListContextResultsChatInputPanelButtonItemNode: ListViewItem
strongSelf.item = item
strongSelf.separatorNode.backgroundColor = item.theme.list.itemPlainSeparatorColor
- strongSelf.topSeparatorNode.backgroundColor = item.theme.list.itemPlainSeparatorColor
let titleOffsetY: CGFloat
switch item.style {
@@ -172,7 +166,6 @@ final class VerticalListContextResultsChatInputPanelButtonItemNode: ListViewItem
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: floor((params.width - titleLayout.size.width) / 2.0), y: floor((nodeLayout.contentSize.height - titleLayout.size.height) / 2.0) + titleOffsetY), size: titleLayout.size)
- strongSelf.topSeparatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: params.width, height: UIScreenPixel))
strongSelf.separatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: nodeLayout.contentSize.height - UIScreenPixel), size: CGSize(width: params.width, height: UIScreenPixel))
strongSelf.buttonNode.frame = CGRect(origin: CGPoint(), size: nodeLayout.contentSize)
diff --git a/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.h b/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.h
index 91fb9d6141..c65fd7a175 100644
--- a/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.h
+++ b/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.h
@@ -4,6 +4,7 @@
double animationDurationFactorImpl();
CABasicAnimation * _Nonnull makeSpringAnimationImpl(NSString * _Nonnull keyPath);
+CABasicAnimation * _Nonnull make26SpringAnimationImpl(NSString * _Nonnull keyPath, double duration);
CABasicAnimation * _Nonnull makeSpringBounceAnimationImpl(NSString * _Nonnull keyPath, CGFloat initialVelocity, CGFloat damping);
CGFloat springAnimationValueAtImpl(CABasicAnimation * _Nonnull animation, CGFloat t);
@@ -36,3 +37,5 @@ void setLayerDisableScreenshots(CALayer * _Nonnull layer, bool disableScreenshot
bool getLayerDisableScreenshots(CALayer * _Nonnull layer);
void setLayerContentsMaskMode(CALayer * _Nonnull layer, bool maskMode);
+
+void setMonochromaticEffectImpl(UIView * _Nonnull view, bool isEnabled);
diff --git a/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.m b/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.m
index e1e78f986f..a3f7bc1e81 100644
--- a/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.m
+++ b/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.m
@@ -61,6 +61,24 @@ CABasicAnimation * _Nonnull makeSpringAnimationImpl(NSString * _Nonnull keyPath)
return springAnimation;
}
+CABasicAnimation * _Nonnull make26SpringAnimationImpl(NSString * _Nonnull keyPath, double duration) {
+ CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:keyPath];
+ springAnimation.mass = 1.0f;
+ springAnimation.stiffness = 555.027;
+ springAnimation.damping = 47.118;
+ springAnimation.duration = duration;
+ springAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
+ if (@available(iOS 17.0, *)) {
+ springAnimation.allowsOverdamping = false;
+ }
+ if (@available(iOS 15.0, *)) {
+ [springAnimation setValue:@(1048619) forKey:@"highFrameRateReason"];
+ springAnimation.preferredFrameRateRange = CAFrameRateRangeMake(80.0, 120.0, 120.0);
+ }
+
+ return springAnimation;
+}
+
CABasicAnimation * _Nonnull makeSpringBounceAnimationImpl(NSString * _Nonnull keyPath, CGFloat initialVelocity, CGFloat damping) {
CASpringAnimation *springAnimation = [CASpringAnimation animationWithKeyPath:keyPath];
springAnimation.mass = 5.0f;
@@ -134,6 +152,20 @@ static void setBoolField(NSObject *object, NSString *name, BOOL value) {
[inv invoke];
}
+static void setLongLongField(NSObject *object, NSString *name, long long value) {
+ SEL selector = NSSelectorFromString(name);
+ NSMethodSignature *signature = [[object class] instanceMethodSignatureForSelector:selector];
+ if (signature == nil) {
+ return;
+ }
+
+ NSInvocation *inv = [NSInvocation invocationWithMethodSignature:signature];
+ [inv setSelector:selector];
+ [inv setArgument:&value atIndex:2];
+ [inv setTarget:object];
+ [inv invoke];
+}
+
UIBlurEffect *makeCustomZoomBlurEffectImpl(bool isLight) {
if (@available(iOS 13.0, *)) {
if (isLight) {
@@ -299,3 +331,27 @@ void setLayerContentsMaskMode(CALayer * _Nonnull layer, bool maskMode) {
[layer setValue:@"RGBA" forKey:key];
}
}
+
+void setMonochromaticEffectImpl(UIView * _Nonnull view, bool isEnabled) {
+ if (@available(iOS 26.0, *)) {
+ static NSString *key1 = nil;
+ static NSString *key2 = nil;
+ static NSString *key3 = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ key1 = [[@"_" stringByAppendingString:@"setAllows"] stringByAppendingString:@"MonochromaticTreatment:"];
+ key2 = [[@"_" stringByAppendingString:@"setEnable"] stringByAppendingString:@"MonochromaticTreatment:"];
+ key3 = [[@"_" stringByAppendingString:@"set"] stringByAppendingString:@"MonochromaticTreatment:"];
+ });
+
+ if (isEnabled) {
+ setBoolField(view, key1, true);
+ setBoolField(view, key2, true);
+ setLongLongField(view, key3, 2);
+ } else {
+ setBoolField(view, key1, false);
+ setBoolField(view, key2, false);
+ setLongLongField(view, key3, 0);
+ }
+ }
+}