mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-18 11:30:04 +00:00
Merge commit 'f2b219b3df9f38c223796e47c3d9463661ff4e07'
This commit is contained in:
commit
a19bb79f90
@ -29,7 +29,7 @@ kernel vec4 alphaFrame(__sample s, __sample m) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createVideoComposition(for playerItem: AVPlayerItem) -> AVVideoComposition? {
|
private func createVideoComposition(for playerItem: AVPlayerItem, ready: @escaping () -> Void) -> AVVideoComposition? {
|
||||||
let videoSize = CGSize(width: playerItem.presentationSize.width, height: playerItem.presentationSize.height / 2.0)
|
let videoSize = CGSize(width: playerItem.presentationSize.width, height: playerItem.presentationSize.height / 2.0)
|
||||||
if #available(iOSApplicationExtension 9.0, *) {
|
if #available(iOSApplicationExtension 9.0, *) {
|
||||||
let composition = AVMutableVideoComposition(asset: playerItem.asset, applyingCIFiltersWithHandler: { request in
|
let composition = AVMutableVideoComposition(asset: playerItem.asset, applyingCIFiltersWithHandler: { request in
|
||||||
@ -39,7 +39,8 @@ private func createVideoComposition(for playerItem: AVPlayerItem) -> AVVideoComp
|
|||||||
filter.inputImage = request.sourceImage.cropped(to: alphaRect)
|
filter.inputImage = request.sourceImage.cropped(to: alphaRect)
|
||||||
.transformed(by: CGAffineTransform(translationX: 0, y: -sourceRect.height))
|
.transformed(by: CGAffineTransform(translationX: 0, y: -sourceRect.height))
|
||||||
filter.maskImage = request.sourceImage.cropped(to: sourceRect)
|
filter.maskImage = request.sourceImage.cropped(to: sourceRect)
|
||||||
return request.finish(with: filter.outputImage!, context: nil)
|
request.finish(with: filter.outputImage!, context: nil)
|
||||||
|
ready()
|
||||||
})
|
})
|
||||||
composition.renderSize = videoSize
|
composition.renderSize = videoSize
|
||||||
return composition
|
return composition
|
||||||
@ -60,6 +61,19 @@ private final class StickerAnimationNode: ASDisplayNode {
|
|||||||
|
|
||||||
var started: () -> Void = {}
|
var started: () -> Void = {}
|
||||||
|
|
||||||
|
var ready = false
|
||||||
|
var visibility = false {
|
||||||
|
didSet {
|
||||||
|
if self.visibility {
|
||||||
|
if self.ready {
|
||||||
|
self.player?.play()
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
self.player?.pause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var player: AVPlayer? {
|
var player: AVPlayer? {
|
||||||
get {
|
get {
|
||||||
if self.isNodeLoaded {
|
if self.isNodeLoaded {
|
||||||
@ -69,13 +83,7 @@ private final class StickerAnimationNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if let player = self.playerLayer.player {
|
|
||||||
player.removeObserver(self, forKeyPath: #keyPath(AVPlayer.rate))
|
|
||||||
}
|
|
||||||
self.playerLayer.player = newValue
|
self.playerLayer.player = newValue
|
||||||
if let newValue = newValue {
|
|
||||||
newValue.addObserver(self, forKeyPath: #keyPath(AVPlayer.rate), options: [], context: nil)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +103,7 @@ private final class StickerAnimationNode: ASDisplayNode {
|
|||||||
self.setLayerBlock({
|
self.setLayerBlock({
|
||||||
let layer = AVPlayerLayer()
|
let layer = AVPlayerLayer()
|
||||||
layer.isHidden = true
|
layer.isHidden = true
|
||||||
|
layer.videoGravity = .resize
|
||||||
if #available(iOSApplicationExtension 9.0, *) {
|
if #available(iOSApplicationExtension 9.0, *) {
|
||||||
layer.pixelBufferAttributes = [(kCVPixelBufferPixelFormatTypeKey as String): kCVPixelFormatType_32BGRA]
|
layer.pixelBufferAttributes = [(kCVPixelBufferPixelFormatTypeKey as String): kCVPixelFormatType_32BGRA]
|
||||||
}
|
}
|
||||||
@ -149,31 +158,22 @@ private final class StickerAnimationNode: ASDisplayNode {
|
|||||||
if let playerItem = object as? AVPlayerItem, playerItem === self.playerItem {
|
if let playerItem = object as? AVPlayerItem, playerItem === self.playerItem {
|
||||||
if case .readyToPlay = playerItem.status, playerItem.videoComposition == nil {
|
if case .readyToPlay = playerItem.status, playerItem.videoComposition == nil {
|
||||||
playerItem.seekingWaitsForVideoCompositionRendering = true
|
playerItem.seekingWaitsForVideoCompositionRendering = true
|
||||||
let composition = createVideoComposition(for: playerItem)
|
let composition = createVideoComposition(for: playerItem, ready: { [weak self] in
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
self?.playerLayer.isHidden = false
|
||||||
|
self?.started()
|
||||||
|
}
|
||||||
|
})
|
||||||
playerItem.videoComposition = composition
|
playerItem.videoComposition = composition
|
||||||
//playerItem.videoComposition = nil
|
ready = true
|
||||||
//playerItem.videoComposition = composition
|
if self.visibility {
|
||||||
self.player?.play()
|
self.player?.play()
|
||||||
}
|
}
|
||||||
} else if let player = object as? AVPlayer, player === self.player {
|
|
||||||
if self.playerLayer.isHidden && player.rate > 0.0 {
|
|
||||||
//Queue.mainQueue().after(0.2) {
|
|
||||||
self.playerLayer.isHidden = false
|
|
||||||
self.started()
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
return super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func play() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func reset() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||||
@ -244,13 +244,25 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
self.view.addGestureRecognizer(replyRecognizer)
|
self.view.addGestureRecognizer(replyRecognizer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override var visibility: ListViewItemNodeVisibility {
|
||||||
|
didSet {
|
||||||
|
if self.visibility != oldValue {
|
||||||
|
switch self.visibility {
|
||||||
|
case .visible:
|
||||||
|
self.animationNode.visibility = true
|
||||||
|
case .none:
|
||||||
|
self.animationNode.visibility = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func setupItem(_ item: ChatMessageItem) {
|
override func setupItem(_ item: ChatMessageItem) {
|
||||||
super.setupItem(item)
|
super.setupItem(item)
|
||||||
|
|
||||||
for media in item.message.media {
|
for media in item.message.media {
|
||||||
if let telegramFile = media as? TelegramMediaFile {
|
if let telegramFile = media as? TelegramMediaFile {
|
||||||
if self.telegramFile != telegramFile {
|
if self.telegramFile?.id != telegramFile.id {
|
||||||
|
|
||||||
self.telegramFile = telegramFile
|
self.telegramFile = telegramFile
|
||||||
self.imageNode.setSignal(chatMessageSticker(account: item.context.account, file: telegramFile, small: false, thumbnail: true))
|
self.imageNode.setSignal(chatMessageSticker(account: item.context.account, file: telegramFile, small: false, thumbnail: true))
|
||||||
self.animationNode.setup(account: item.context.account, fileReference: .message(message: MessageReference(item.message), media: telegramFile))
|
self.animationNode.setup(account: item.context.account, fileReference: .message(message: MessageReference(item.message), media: telegramFile))
|
||||||
|
@ -89,18 +89,6 @@ func textAttributedStringForStateText(_ stateText: NSAttributedString, fontSize:
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private func textMentionRangesEqual(_ lhs: [(NSRange, ChatTextInputTextMentionAttribute)], _ rhs: [(NSRange, ChatTextInputTextMentionAttribute)]) -> Bool {
|
|
||||||
if lhs.count != rhs.count {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
for i in 0 ..< lhs.count {
|
|
||||||
if lhs[i].0 != rhs[i].0 || lhs[i].1.peerId != rhs[i].1.peerId {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
final class ChatTextInputTextMentionAttribute: NSObject {
|
final class ChatTextInputTextMentionAttribute: NSObject {
|
||||||
let peerId: PeerId
|
let peerId: PeerId
|
||||||
|
|
||||||
@ -119,6 +107,18 @@ final class ChatTextInputTextMentionAttribute: NSObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func textMentionRangesEqual(_ lhs: [(NSRange, ChatTextInputTextMentionAttribute)], _ rhs: [(NSRange, ChatTextInputTextMentionAttribute)]) -> Bool {
|
||||||
|
if lhs.count != rhs.count {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for i in 0 ..< lhs.count {
|
||||||
|
if lhs[i].0 != rhs[i].0 || lhs[i].1.peerId != rhs[i].1.peerId {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
final class ChatTextInputTextUrlAttribute: NSObject {
|
final class ChatTextInputTextUrlAttribute: NSObject {
|
||||||
let url: String
|
let url: String
|
||||||
|
|
||||||
@ -137,16 +137,19 @@ final class ChatTextInputTextUrlAttribute: NSObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: PresentationTheme, baseFontSize: CGFloat) {
|
private func textUrlRangesEqual(_ lhs: [(NSRange, ChatTextInputTextUrlAttribute)], _ rhs: [(NSRange, ChatTextInputTextUrlAttribute)]) -> Bool {
|
||||||
guard let initialAttributedText = textNode.attributedText, initialAttributedText.length != 0 else {
|
if lhs.count != rhs.count {
|
||||||
return
|
return false
|
||||||
|
}
|
||||||
|
for i in 0 ..< lhs.count {
|
||||||
|
if lhs[i].0 != rhs[i].0 || lhs[i].1.url != rhs[i].1.url {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
let text: NSString = initialAttributedText.string as NSString
|
private func refreshTextMentions(text: NSString, initialAttributedText: NSAttributedString, attributedText: NSMutableAttributedString, fullRange: NSRange) {
|
||||||
let fullRange = NSRange(location: 0, length: initialAttributedText.length)
|
|
||||||
|
|
||||||
let attributedText = NSMutableAttributedString(attributedString: stateAttributedStringForText(initialAttributedText))
|
|
||||||
|
|
||||||
var textMentionRanges: [(NSRange, ChatTextInputTextMentionAttribute)] = []
|
var textMentionRanges: [(NSRange, ChatTextInputTextMentionAttribute)] = []
|
||||||
initialAttributedText.enumerateAttribute(ChatTextInputAttributes.textMention, in: fullRange, options: [], using: { value, range, _ in
|
initialAttributedText.enumerateAttribute(ChatTextInputAttributes.textMention, in: fullRange, options: [], using: { value, range, _ in
|
||||||
if let value = value as? ChatTextInputTextMentionAttribute {
|
if let value = value as? ChatTextInputTextMentionAttribute {
|
||||||
@ -260,8 +263,142 @@ func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: Prese
|
|||||||
attributedText.addAttribute(ChatTextInputAttributes.textMention, value: ChatTextInputTextMentionAttribute(peerId: attribute.peerId), range: range)
|
attributedText.addAttribute(ChatTextInputAttributes.textMention, value: ChatTextInputTextMentionAttribute(peerId: attribute.peerId), range: range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let resultAttributedText = textAttributedStringForStateText(attributedText, fontSize: baseFontSize, textColor: theme.chat.inputPanel.primaryTextColor, accentTextColor: theme.chat.inputPanel.panelControlAccentColor)
|
private func refreshTextUrls(text: NSString, initialAttributedText: NSAttributedString, attributedText: NSMutableAttributedString, fullRange: NSRange) {
|
||||||
|
var textUrlRanges: [(NSRange, ChatTextInputTextUrlAttribute)] = []
|
||||||
|
initialAttributedText.enumerateAttribute(ChatTextInputAttributes.textUrl, in: fullRange, options: [], using: { value, range, _ in
|
||||||
|
if let value = value as? ChatTextInputTextUrlAttribute {
|
||||||
|
textUrlRanges.append((range, value))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
textUrlRanges.sort(by: { $0.0.location < $1.0.location })
|
||||||
|
let initialTextUrlRanges = textUrlRanges
|
||||||
|
|
||||||
|
for i in 0 ..< textUrlRanges.count {
|
||||||
|
let range = textUrlRanges[i].0
|
||||||
|
|
||||||
|
var validLower = range.lowerBound
|
||||||
|
inner1: for i in range.lowerBound ..< range.upperBound {
|
||||||
|
if let c = UnicodeScalar(text.character(at: i)) {
|
||||||
|
if alphanumericCharacters.contains(c) || c == " " as UnicodeScalar {
|
||||||
|
validLower = i
|
||||||
|
break inner1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break inner1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var validUpper = range.upperBound
|
||||||
|
inner2: for i in (validLower ..< range.upperBound).reversed() {
|
||||||
|
if let c = UnicodeScalar(text.character(at: i)) {
|
||||||
|
if alphanumericCharacters.contains(c) || c == " " as UnicodeScalar {
|
||||||
|
validUpper = i + 1
|
||||||
|
break inner2
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break inner2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let minLower = (i == 0) ? fullRange.lowerBound : textUrlRanges[i - 1].0.upperBound
|
||||||
|
inner3: for i in (minLower ..< validLower).reversed() {
|
||||||
|
if let c = UnicodeScalar(text.character(at: i)) {
|
||||||
|
if alphanumericCharacters.contains(c) {
|
||||||
|
validLower = i
|
||||||
|
} else {
|
||||||
|
break inner3
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break inner3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let maxUpper = (i == textUrlRanges.count - 1) ? fullRange.upperBound : textUrlRanges[i + 1].0.lowerBound
|
||||||
|
inner3: for i in validUpper ..< maxUpper {
|
||||||
|
if let c = UnicodeScalar(text.character(at: i)) {
|
||||||
|
if alphanumericCharacters.contains(c) {
|
||||||
|
validUpper = i + 1
|
||||||
|
} else {
|
||||||
|
break inner3
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break inner3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textUrlRanges[i] = (NSRange(location: validLower, length: validUpper - validLower), textUrlRanges[i].1)
|
||||||
|
}
|
||||||
|
|
||||||
|
textUrlRanges = textUrlRanges.filter({ $0.0.length > 0 })
|
||||||
|
|
||||||
|
while textUrlRanges.count > 1 {
|
||||||
|
var hadReductions = false
|
||||||
|
outer: for i in 0 ..< textUrlRanges.count - 1 {
|
||||||
|
if textUrlRanges[i].1 === textUrlRanges[i + 1].1 {
|
||||||
|
var combine = true
|
||||||
|
inner: for j in textUrlRanges[i].0.upperBound ..< textUrlRanges[i + 1].0.lowerBound {
|
||||||
|
if let c = UnicodeScalar(text.character(at: j)) {
|
||||||
|
if alphanumericCharacters.contains(c) || c == " " as UnicodeScalar {
|
||||||
|
} else {
|
||||||
|
combine = false
|
||||||
|
break inner
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
combine = false
|
||||||
|
break inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if combine {
|
||||||
|
hadReductions = true
|
||||||
|
textUrlRanges[i] = (NSRange(location: textUrlRanges[i].0.lowerBound, length: textUrlRanges[i + 1].0.upperBound - textUrlRanges[i].0.lowerBound), textUrlRanges[i].1)
|
||||||
|
textUrlRanges.remove(at: i + 1)
|
||||||
|
break outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !hadReductions {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if textUrlRanges.count > 1 {
|
||||||
|
outer: for i in (1 ..< textUrlRanges.count).reversed() {
|
||||||
|
for j in 0 ..< i {
|
||||||
|
if textUrlRanges[j].1 === textUrlRanges[i].1 {
|
||||||
|
textUrlRanges.remove(at: i)
|
||||||
|
continue outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !textUrlRangesEqual(textUrlRanges, initialTextUrlRanges) {
|
||||||
|
attributedText.removeAttribute(ChatTextInputAttributes.textUrl, range: fullRange)
|
||||||
|
for (range, attribute) in textUrlRanges {
|
||||||
|
attributedText.addAttribute(ChatTextInputAttributes.textUrl, value: ChatTextInputTextUrlAttribute(url: attribute.url), range: range)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: PresentationTheme, baseFontSize: CGFloat) {
|
||||||
|
guard var initialAttributedText = textNode.attributedText, initialAttributedText.length != 0 else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var text: NSString = initialAttributedText.string as NSString
|
||||||
|
var fullRange = NSRange(location: 0, length: initialAttributedText.length)
|
||||||
|
var attributedText = NSMutableAttributedString(attributedString: stateAttributedStringForText(initialAttributedText))
|
||||||
|
refreshTextMentions(text: text, initialAttributedText: initialAttributedText, attributedText: attributedText, fullRange: fullRange)
|
||||||
|
|
||||||
|
var resultAttributedText = textAttributedStringForStateText(attributedText, fontSize: baseFontSize, textColor: theme.chat.inputPanel.primaryTextColor, accentTextColor: theme.chat.inputPanel.panelControlAccentColor)
|
||||||
|
|
||||||
|
text = resultAttributedText.string as NSString
|
||||||
|
fullRange = NSRange(location: 0, length: initialAttributedText.length)
|
||||||
|
attributedText = NSMutableAttributedString(attributedString: stateAttributedStringForText(resultAttributedText))
|
||||||
|
refreshTextUrls(text: text, initialAttributedText: resultAttributedText, attributedText: attributedText, fullRange: fullRange)
|
||||||
|
|
||||||
|
resultAttributedText = textAttributedStringForStateText(attributedText, fontSize: baseFontSize, textColor: theme.chat.inputPanel.primaryTextColor, accentTextColor: theme.chat.inputPanel.panelControlAccentColor)
|
||||||
|
|
||||||
if !resultAttributedText.isEqual(to: initialAttributedText) {
|
if !resultAttributedText.isEqual(to: initialAttributedText) {
|
||||||
textNode.textView.textStorage.removeAttribute(NSAttributedStringKey.font, range: fullRange)
|
textNode.textView.textStorage.removeAttribute(NSAttributedStringKey.font, range: fullRange)
|
||||||
@ -299,13 +436,13 @@ func refreshChatTextInputAttributes(_ textNode: ASEditableTextNode, theme: Prese
|
|||||||
if !fontAttributes.isEmpty {
|
if !fontAttributes.isEmpty {
|
||||||
var font: UIFont?
|
var font: UIFont?
|
||||||
if fontAttributes == [.bold, .italic, .monospace] {
|
if fontAttributes == [.bold, .italic, .monospace] {
|
||||||
|
font = Font.semiboldItalicMonospace(baseFontSize)
|
||||||
} else if fontAttributes == [.bold, .italic] {
|
} else if fontAttributes == [.bold, .italic] {
|
||||||
font = Font.semiboldItalic(baseFontSize)
|
font = Font.semiboldItalic(baseFontSize)
|
||||||
} else if fontAttributes == [.bold, .monospace] {
|
} else if fontAttributes == [.bold, .monospace] {
|
||||||
|
font = Font.semiboldMonospace(baseFontSize)
|
||||||
} else if fontAttributes == [.italic, .monospace] {
|
} else if fontAttributes == [.italic, .monospace] {
|
||||||
|
font = Font.italicMonospace(baseFontSize)
|
||||||
} else if fontAttributes == [.bold] {
|
} else if fontAttributes == [.bold] {
|
||||||
font = Font.semibold(baseFontSize)
|
font = Font.semibold(baseFontSize)
|
||||||
} else if fontAttributes == [.italic] {
|
} else if fontAttributes == [.italic] {
|
||||||
|
@ -6,13 +6,14 @@ import Postbox
|
|||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
|
||||||
private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTextNodeDelegate {
|
private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTextNodeDelegate {
|
||||||
private let theme: PresentationTheme
|
private var theme: PresentationTheme
|
||||||
private let backgroundNode: ASImageNode
|
private let backgroundNode: ASImageNode
|
||||||
private let textInputNode: EditableTextNode
|
private let textInputNode: EditableTextNode
|
||||||
private let placeholderNode: ASTextNode
|
private let placeholderNode: ASTextNode
|
||||||
|
|
||||||
var updateHeight: (() -> Void)?
|
var updateHeight: (() -> Void)?
|
||||||
var complete: (() -> Void)?
|
var complete: (() -> Void)?
|
||||||
|
var textChanged: ((String) -> Void)?
|
||||||
|
|
||||||
private let backgroundInsets = UIEdgeInsets(top: 8.0, left: 16.0, bottom: 15.0, right: 16.0)
|
private let backgroundInsets = UIEdgeInsets(top: 8.0, left: 16.0, bottom: 15.0, right: 16.0)
|
||||||
private let inputInsets = UIEdgeInsets(top: 5.0, left: 12.0, bottom: 5.0, right: 12.0)
|
private let inputInsets = UIEdgeInsets(top: 5.0, left: 12.0, bottom: 5.0, right: 12.0)
|
||||||
@ -41,7 +42,7 @@ private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTex
|
|||||||
self.backgroundNode.isLayerBacked = true
|
self.backgroundNode.isLayerBacked = true
|
||||||
self.backgroundNode.displaysAsynchronously = false
|
self.backgroundNode.displaysAsynchronously = false
|
||||||
self.backgroundNode.displayWithoutProcessing = true
|
self.backgroundNode.displayWithoutProcessing = true
|
||||||
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 33.0, color: theme.actionSheet.itemBackgroundColor.withAlphaComponent(1.0), strokeColor: theme.actionSheet.inputBackgroundColor, strokeWidth: 1.0)
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 33.0, color: theme.actionSheet.inputHollowBackgroundColor, strokeColor: theme.actionSheet.inputBorderColor, strokeWidth: 1.0)
|
||||||
|
|
||||||
self.textInputNode = EditableTextNode()
|
self.textInputNode = EditableTextNode()
|
||||||
self.textInputNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(17.0), NSAttributedStringKey.foregroundColor.rawValue: theme.actionSheet.inputTextColor]
|
self.textInputNode.typingAttributes = [NSAttributedStringKey.font.rawValue: Font.regular(17.0), NSAttributedStringKey.foregroundColor.rawValue: theme.actionSheet.inputTextColor]
|
||||||
@ -52,6 +53,7 @@ private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTex
|
|||||||
self.textInputNode.keyboardType = .URL
|
self.textInputNode.keyboardType = .URL
|
||||||
self.textInputNode.autocapitalizationType = .none
|
self.textInputNode.autocapitalizationType = .none
|
||||||
self.textInputNode.returnKeyType = .done
|
self.textInputNode.returnKeyType = .done
|
||||||
|
self.textInputNode.autocorrectionType = .no
|
||||||
|
|
||||||
self.placeholderNode = ASTextNode()
|
self.placeholderNode = ASTextNode()
|
||||||
self.placeholderNode.isUserInteractionEnabled = false
|
self.placeholderNode.isUserInteractionEnabled = false
|
||||||
@ -67,6 +69,14 @@ private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTex
|
|||||||
self.addSubnode(self.placeholderNode)
|
self.addSubnode(self.placeholderNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updateTheme(_ theme: PresentationTheme) {
|
||||||
|
self.theme = theme
|
||||||
|
|
||||||
|
self.backgroundNode.image = generateStretchableFilledCircleImage(diameter: 33.0, color: theme.actionSheet.inputHollowBackgroundColor, strokeColor: theme.actionSheet.inputBorderColor, strokeWidth: 1.0)
|
||||||
|
self.textInputNode.keyboardAppearance = theme.chatList.searchBarKeyboardColor.keyboardAppearance
|
||||||
|
self.placeholderNode.attributedText = NSAttributedString(string: self.placeholderNode.attributedText?.string ?? "", font: Font.regular(17.0), textColor: self.theme.actionSheet.inputPlaceholderColor)
|
||||||
|
}
|
||||||
|
|
||||||
func updateLayout(width: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat {
|
func updateLayout(width: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat {
|
||||||
let backgroundInsets = self.backgroundInsets
|
let backgroundInsets = self.backgroundInsets
|
||||||
let inputInsets = self.inputInsets
|
let inputInsets = self.inputInsets
|
||||||
@ -79,7 +89,7 @@ private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTex
|
|||||||
transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame)
|
transition.updateFrame(node: self.backgroundNode, frame: backgroundFrame)
|
||||||
|
|
||||||
let placeholderSize = self.placeholderNode.measure(backgroundFrame.size)
|
let placeholderSize = self.placeholderNode.measure(backgroundFrame.size)
|
||||||
transition.updateFrame(node: self.placeholderNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + floor((backgroundFrame.size.width - placeholderSize.width) / 2.0), y: backgroundFrame.minY + floor((backgroundFrame.size.height - placeholderSize.height) / 2.0)), size: placeholderSize))
|
transition.updateFrame(node: self.placeholderNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + inputInsets.left, y: backgroundFrame.minY + floor((backgroundFrame.size.height - placeholderSize.height) / 2.0)), size: placeholderSize))
|
||||||
|
|
||||||
transition.updateFrame(node: self.textInputNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + inputInsets.left, y: backgroundFrame.minY), size: CGSize(width: backgroundFrame.size.width - inputInsets.left - inputInsets.right - accessoryButtonsWidth, height: backgroundFrame.size.height)))
|
transition.updateFrame(node: self.textInputNode, frame: CGRect(origin: CGPoint(x: backgroundFrame.minX + inputInsets.left, y: backgroundFrame.minY), size: CGSize(width: backgroundFrame.size.width - inputInsets.left - inputInsets.right - accessoryButtonsWidth, height: backgroundFrame.size.height)))
|
||||||
|
|
||||||
@ -96,13 +106,7 @@ private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTex
|
|||||||
|
|
||||||
@objc func editableTextNodeDidUpdateText(_ editableTextNode: ASEditableTextNode) {
|
@objc func editableTextNodeDidUpdateText(_ editableTextNode: ASEditableTextNode) {
|
||||||
self.updateTextNodeText(animated: true)
|
self.updateTextNodeText(animated: true)
|
||||||
}
|
self.textChanged?(editableTextNode.textView.text)
|
||||||
|
|
||||||
func editableTextNodeDidBeginEditing(_ editableTextNode: ASEditableTextNode) {
|
|
||||||
self.placeholderNode.isHidden = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func editableTextNodeDidFinishEditing(_ editableTextNode: ASEditableTextNode) {
|
|
||||||
self.placeholderNode.isHidden = !(editableTextNode.textView.text ?? "").isEmpty
|
self.placeholderNode.isHidden = !(editableTextNode.textView.text ?? "").isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,17 +147,19 @@ private final class ChatTextLinkEditInputFieldNode: ASDisplayNode, ASEditableTex
|
|||||||
|
|
||||||
|
|
||||||
private final class ChatTextLinkEditContentActionNode: HighlightableButtonNode {
|
private final class ChatTextLinkEditContentActionNode: HighlightableButtonNode {
|
||||||
private let backgroundNode: ASDisplayNode
|
private var theme: AlertControllerTheme
|
||||||
|
|
||||||
let action: TextAlertAction
|
let action: TextAlertAction
|
||||||
|
|
||||||
|
private let backgroundNode: ASDisplayNode
|
||||||
|
|
||||||
init(theme: AlertControllerTheme, action: TextAlertAction) {
|
init(theme: AlertControllerTheme, action: TextAlertAction) {
|
||||||
|
self.theme = theme
|
||||||
|
self.action = action
|
||||||
|
|
||||||
self.backgroundNode = ASDisplayNode()
|
self.backgroundNode = ASDisplayNode()
|
||||||
self.backgroundNode.isLayerBacked = true
|
self.backgroundNode.isLayerBacked = true
|
||||||
self.backgroundNode.alpha = 0.0
|
self.backgroundNode.alpha = 0.0
|
||||||
|
|
||||||
self.action = action
|
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.titleNode.maximumNumberOfLines = 2
|
self.titleNode.maximumNumberOfLines = 2
|
||||||
@ -176,16 +182,27 @@ private final class ChatTextLinkEditContentActionNode: HighlightableButtonNode {
|
|||||||
self.updateTheme(theme)
|
self.updateTheme(theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateTheme(_ theme: AlertControllerTheme) {
|
var actionEnabled: Bool = true {
|
||||||
self.backgroundNode.backgroundColor = theme.highlightedItemColor
|
didSet {
|
||||||
|
self.isUserInteractionEnabled = self.actionEnabled
|
||||||
|
self.updateTitle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateTheme(_ theme: AlertControllerTheme) {
|
||||||
|
self.theme = theme
|
||||||
|
self.backgroundNode.backgroundColor = theme.highlightedItemColor
|
||||||
|
self.updateTitle()
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateTitle() {
|
||||||
var font = Font.regular(17.0)
|
var font = Font.regular(17.0)
|
||||||
var color = theme.accentColor
|
var color: UIColor
|
||||||
switch self.action.type {
|
switch self.action.type {
|
||||||
case .defaultAction, .genericAction:
|
case .defaultAction, .genericAction:
|
||||||
break
|
color = self.actionEnabled ? self.theme.accentColor : self.theme.disabledColor
|
||||||
case .destructiveAction:
|
case .destructiveAction:
|
||||||
color = theme.destructiveColor
|
color = self.actionEnabled ? self.theme.destructiveColor : self.theme.disabledColor
|
||||||
}
|
}
|
||||||
switch self.action.type {
|
switch self.action.type {
|
||||||
case .defaultAction:
|
case .defaultAction:
|
||||||
@ -219,7 +236,7 @@ private final class ChatTextLinkEditAlertContentNode: AlertContentNode {
|
|||||||
|
|
||||||
private let titleNode: ASTextNode
|
private let titleNode: ASTextNode
|
||||||
private let textNode: ASTextNode
|
private let textNode: ASTextNode
|
||||||
private let inputFieldNode: ChatTextLinkEditInputFieldNode
|
let inputFieldNode: ChatTextLinkEditInputFieldNode
|
||||||
|
|
||||||
private let actionNodesSeparator: ASDisplayNode
|
private let actionNodesSeparator: ASDisplayNode
|
||||||
private let actionNodes: [ChatTextLinkEditContentActionNode]
|
private let actionNodes: [ChatTextLinkEditContentActionNode]
|
||||||
@ -250,9 +267,8 @@ private final class ChatTextLinkEditAlertContentNode: AlertContentNode {
|
|||||||
self.textNode = ASTextNode()
|
self.textNode = ASTextNode()
|
||||||
self.textNode.maximumNumberOfLines = 2
|
self.textNode.maximumNumberOfLines = 2
|
||||||
|
|
||||||
self.inputFieldNode = ChatTextLinkEditInputFieldNode(theme: ptheme, placeholder: "")
|
self.inputFieldNode = ChatTextLinkEditInputFieldNode(theme: ptheme, placeholder: strings.TextFormat_AddLinkPlaceholder)
|
||||||
self.inputFieldNode.text = link ?? ""
|
self.inputFieldNode.text = link ?? ""
|
||||||
self.inputFieldNode.placeholder = strings.TextFormat_AddLinkPlaceholder
|
|
||||||
|
|
||||||
self.actionNodesSeparator = ASDisplayNode()
|
self.actionNodesSeparator = ASDisplayNode()
|
||||||
self.actionNodesSeparator.isLayerBacked = true
|
self.actionNodesSeparator.isLayerBacked = true
|
||||||
@ -283,6 +299,7 @@ private final class ChatTextLinkEditAlertContentNode: AlertContentNode {
|
|||||||
for actionNode in self.actionNodes {
|
for actionNode in self.actionNodes {
|
||||||
self.addSubnode(actionNode)
|
self.addSubnode(actionNode)
|
||||||
}
|
}
|
||||||
|
self.actionNodes.last?.actionEnabled = !(link ?? "").isEmpty
|
||||||
|
|
||||||
for separatorNode in self.actionVerticalSeparators {
|
for separatorNode in self.actionVerticalSeparators {
|
||||||
self.addSubnode(separatorNode)
|
self.addSubnode(separatorNode)
|
||||||
@ -296,6 +313,12 @@ private final class ChatTextLinkEditAlertContentNode: AlertContentNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.inputFieldNode.textChanged = { [weak self] text in
|
||||||
|
if let strongSelf = self, let lastNode = strongSelf.actionNodes.last {
|
||||||
|
lastNode.actionEnabled = !text.isEmpty
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.updateTheme(theme)
|
self.updateTheme(theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,8 +468,6 @@ private final class ChatTextLinkEditAlertContentNode: AlertContentNode {
|
|||||||
|
|
||||||
func chatTextLinkEditController(sharedContext: SharedAccountContext, account: Account, text: String, link: String?, apply: @escaping (String?) -> Void) -> AlertController {
|
func chatTextLinkEditController(sharedContext: SharedAccountContext, account: Account, text: String, link: String?, apply: @escaping (String?) -> Void) -> AlertController {
|
||||||
let presentationData = sharedContext.currentPresentationData.with { $0 }
|
let presentationData = sharedContext.currentPresentationData.with { $0 }
|
||||||
let theme = presentationData.theme
|
|
||||||
let strings = presentationData.strings
|
|
||||||
|
|
||||||
var dismissImpl: ((Bool) -> Void)?
|
var dismissImpl: ((Bool) -> Void)?
|
||||||
var applyImpl: (() -> Void)?
|
var applyImpl: (() -> Void)?
|
||||||
@ -458,7 +479,7 @@ func chatTextLinkEditController(sharedContext: SharedAccountContext, account: Ac
|
|||||||
applyImpl?()
|
applyImpl?()
|
||||||
})]
|
})]
|
||||||
|
|
||||||
let contentNode = ChatTextLinkEditAlertContentNode(theme: AlertControllerTheme(presentationTheme: theme), ptheme: theme, strings: strings, actions: actions, text: text, link: link)
|
let contentNode = ChatTextLinkEditAlertContentNode(theme: AlertControllerTheme(presentationTheme: presentationData.theme), ptheme: presentationData.theme, strings: presentationData.strings, actions: actions, text: text, link: link)
|
||||||
contentNode.complete = {
|
contentNode.complete = {
|
||||||
applyImpl?()
|
applyImpl?()
|
||||||
}
|
}
|
||||||
@ -470,14 +491,7 @@ func chatTextLinkEditController(sharedContext: SharedAccountContext, account: Ac
|
|||||||
if !updatedLink.hasPrefix("http") && !updatedLink.hasPrefix("https") {
|
if !updatedLink.hasPrefix("http") && !updatedLink.hasPrefix("https") {
|
||||||
updatedLink = "http://\(updatedLink)"
|
updatedLink = "http://\(updatedLink)"
|
||||||
}
|
}
|
||||||
if updatedLink.isEmpty {
|
if !updatedLink.isEmpty && isValidUrl(updatedLink) {
|
||||||
if let _ = link {
|
|
||||||
dismissImpl?(true)
|
|
||||||
apply(updatedLink)
|
|
||||||
} else {
|
|
||||||
contentNode.animateError()
|
|
||||||
}
|
|
||||||
} else if isValidUrl(updatedLink) {
|
|
||||||
dismissImpl?(true)
|
dismissImpl?(true)
|
||||||
apply(updatedLink)
|
apply(updatedLink)
|
||||||
} else {
|
} else {
|
||||||
@ -485,7 +499,14 @@ func chatTextLinkEditController(sharedContext: SharedAccountContext, account: Ac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let controller = AlertController(theme: AlertControllerTheme(presentationTheme: theme), contentNode: contentNode)
|
let controller = AlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), contentNode: contentNode)
|
||||||
|
let presentationDataDisposable = sharedContext.presentationData.start(next: { [weak controller, weak contentNode] presentationData in
|
||||||
|
controller?.theme = AlertControllerTheme(presentationTheme: presentationData.theme)
|
||||||
|
contentNode?.inputFieldNode.updateTheme(presentationData.theme)
|
||||||
|
})
|
||||||
|
controller.dismissed = {
|
||||||
|
presentationDataDisposable.dispose()
|
||||||
|
}
|
||||||
dismissImpl = { [weak controller] animated in
|
dismissImpl = { [weak controller] animated in
|
||||||
if animated {
|
if animated {
|
||||||
controller?.dismissAnimated()
|
controller?.dismissAnimated()
|
||||||
|
@ -43,7 +43,7 @@ extension ActionSheetController {
|
|||||||
public extension AlertControllerTheme {
|
public extension AlertControllerTheme {
|
||||||
convenience init(presentationTheme: PresentationTheme) {
|
convenience init(presentationTheme: PresentationTheme) {
|
||||||
let actionSheet = presentationTheme.actionSheet
|
let actionSheet = presentationTheme.actionSheet
|
||||||
self.init(backgroundColor: actionSheet.opaqueItemBackgroundColor, separatorColor: actionSheet.opaqueItemSeparatorColor, highlightedItemColor: actionSheet.opaqueItemHighlightedBackgroundColor, primaryColor: actionSheet.primaryTextColor, secondaryColor: actionSheet.secondaryTextColor, accentColor: actionSheet.controlAccentColor, destructiveColor: actionSheet.destructiveActionTextColor)
|
self.init(backgroundColor: actionSheet.opaqueItemBackgroundColor, separatorColor: actionSheet.opaqueItemSeparatorColor, highlightedItemColor: actionSheet.opaqueItemHighlightedBackgroundColor, primaryColor: actionSheet.primaryTextColor, secondaryColor: actionSheet.secondaryTextColor, accentColor: actionSheet.controlAccentColor, destructiveColor: actionSheet.destructiveActionTextColor, disabledColor: actionSheet.disabledActionTextColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,6 +310,8 @@ private let actionSheet = PresentationThemeActionSheet(
|
|||||||
secondaryTextColor: UIColor(white: 1.0, alpha: 0.5), //!!!
|
secondaryTextColor: UIColor(white: 1.0, alpha: 0.5), //!!!
|
||||||
controlAccentColor: accentColor,
|
controlAccentColor: accentColor,
|
||||||
inputBackgroundColor: UIColor(rgb: 0x182330), //!!!
|
inputBackgroundColor: UIColor(rgb: 0x182330), //!!!
|
||||||
|
inputHollowBackgroundColor: UIColor(rgb: 0x182330),
|
||||||
|
inputBorderColor: UIColor(rgb: 0x182330),
|
||||||
inputPlaceholderColor: UIColor(rgb: 0x8B9197), //!!!
|
inputPlaceholderColor: UIColor(rgb: 0x8B9197), //!!!
|
||||||
inputTextColor: .white,
|
inputTextColor: .white,
|
||||||
inputClearButtonColor: UIColor(rgb: 0x8B9197),
|
inputClearButtonColor: UIColor(rgb: 0x8B9197),
|
||||||
|
@ -308,6 +308,8 @@ private let actionSheet = PresentationThemeActionSheet(
|
|||||||
secondaryTextColor: UIColor(rgb: 0x5e5e5e), //!!!
|
secondaryTextColor: UIColor(rgb: 0x5e5e5e), //!!!
|
||||||
controlAccentColor: accentColor,
|
controlAccentColor: accentColor,
|
||||||
inputBackgroundColor: UIColor(rgb: 0x545454), //!!!
|
inputBackgroundColor: UIColor(rgb: 0x545454), //!!!
|
||||||
|
inputHollowBackgroundColor: UIColor(rgb: 0x545454),
|
||||||
|
inputBorderColor: UIColor(rgb: 0x545454),
|
||||||
inputPlaceholderColor: UIColor(rgb: 0xaaaaaa), //!!!
|
inputPlaceholderColor: UIColor(rgb: 0xaaaaaa), //!!!
|
||||||
inputTextColor: .white,
|
inputTextColor: .white,
|
||||||
inputClearButtonColor: UIColor(rgb: 0xaaaaaa),
|
inputClearButtonColor: UIColor(rgb: 0xaaaaaa),
|
||||||
|
@ -414,11 +414,13 @@ private func makeDefaultPresentationTheme(accentColor: UIColor, serviceBackgroun
|
|||||||
standardActionTextColor: accentColor,
|
standardActionTextColor: accentColor,
|
||||||
opaqueItemSeparatorColor: UIColor(white: 0.9, alpha: 1.0),
|
opaqueItemSeparatorColor: UIColor(white: 0.9, alpha: 1.0),
|
||||||
destructiveActionTextColor: destructiveColor,
|
destructiveActionTextColor: destructiveColor,
|
||||||
disabledActionTextColor: UIColor(rgb: 0x4d4d4d),
|
disabledActionTextColor: UIColor(rgb: 0xb3b3b3),
|
||||||
primaryTextColor: .black,
|
primaryTextColor: .black,
|
||||||
secondaryTextColor: UIColor(rgb: 0x5e5e5e),
|
secondaryTextColor: UIColor(rgb: 0x5e5e5e),
|
||||||
controlAccentColor: accentColor,
|
controlAccentColor: accentColor,
|
||||||
inputBackgroundColor: UIColor(rgb: 0xe9e9e9),
|
inputBackgroundColor: UIColor(rgb: 0xe9e9e9),
|
||||||
|
inputHollowBackgroundColor: .white,
|
||||||
|
inputBorderColor: UIColor(rgb: 0xe4e4e6),
|
||||||
inputPlaceholderColor: UIColor(rgb: 0x818086),
|
inputPlaceholderColor: UIColor(rgb: 0x818086),
|
||||||
inputTextColor: .black,
|
inputTextColor: .black,
|
||||||
inputClearButtonColor: UIColor(rgb: 0x7b7b81),
|
inputClearButtonColor: UIColor(rgb: 0x7b7b81),
|
||||||
|
@ -199,12 +199,14 @@ public final class PresentationThemeActionSheet {
|
|||||||
public let secondaryTextColor: UIColor
|
public let secondaryTextColor: UIColor
|
||||||
public let controlAccentColor: UIColor
|
public let controlAccentColor: UIColor
|
||||||
public let inputBackgroundColor: UIColor
|
public let inputBackgroundColor: UIColor
|
||||||
|
public let inputHollowBackgroundColor: UIColor
|
||||||
|
public let inputBorderColor: UIColor
|
||||||
public let inputPlaceholderColor: UIColor
|
public let inputPlaceholderColor: UIColor
|
||||||
public let inputTextColor: UIColor
|
public let inputTextColor: UIColor
|
||||||
public let inputClearButtonColor: UIColor
|
public let inputClearButtonColor: UIColor
|
||||||
public let checkContentColor: UIColor
|
public let checkContentColor: UIColor
|
||||||
|
|
||||||
init(dimColor: UIColor, backgroundType: PresentationThemeActionSheetBackgroundType, opaqueItemBackgroundColor: UIColor, itemBackgroundColor: UIColor, opaqueItemHighlightedBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, standardActionTextColor: UIColor, opaqueItemSeparatorColor: UIColor, destructiveActionTextColor: UIColor, disabledActionTextColor: UIColor, primaryTextColor: UIColor, secondaryTextColor: UIColor, controlAccentColor: UIColor, inputBackgroundColor: UIColor, inputPlaceholderColor: UIColor, inputTextColor: UIColor, inputClearButtonColor: UIColor, checkContentColor: UIColor) {
|
init(dimColor: UIColor, backgroundType: PresentationThemeActionSheetBackgroundType, opaqueItemBackgroundColor: UIColor, itemBackgroundColor: UIColor, opaqueItemHighlightedBackgroundColor: UIColor, itemHighlightedBackgroundColor: UIColor, standardActionTextColor: UIColor, opaqueItemSeparatorColor: UIColor, destructiveActionTextColor: UIColor, disabledActionTextColor: UIColor, primaryTextColor: UIColor, secondaryTextColor: UIColor, controlAccentColor: UIColor, inputBackgroundColor: UIColor, inputHollowBackgroundColor: UIColor, inputBorderColor: UIColor, inputPlaceholderColor: UIColor, inputTextColor: UIColor, inputClearButtonColor: UIColor, checkContentColor: UIColor) {
|
||||||
self.dimColor = dimColor
|
self.dimColor = dimColor
|
||||||
self.backgroundType = backgroundType
|
self.backgroundType = backgroundType
|
||||||
self.opaqueItemBackgroundColor = opaqueItemBackgroundColor
|
self.opaqueItemBackgroundColor = opaqueItemBackgroundColor
|
||||||
@ -219,6 +221,8 @@ public final class PresentationThemeActionSheet {
|
|||||||
self.secondaryTextColor = secondaryTextColor
|
self.secondaryTextColor = secondaryTextColor
|
||||||
self.controlAccentColor = controlAccentColor
|
self.controlAccentColor = controlAccentColor
|
||||||
self.inputBackgroundColor = inputBackgroundColor
|
self.inputBackgroundColor = inputBackgroundColor
|
||||||
|
self.inputHollowBackgroundColor = inputHollowBackgroundColor
|
||||||
|
self.inputBorderColor = inputBorderColor
|
||||||
self.inputPlaceholderColor = inputPlaceholderColor
|
self.inputPlaceholderColor = inputPlaceholderColor
|
||||||
self.inputTextColor = inputTextColor
|
self.inputTextColor = inputTextColor
|
||||||
self.inputClearButtonColor = inputClearButtonColor
|
self.inputClearButtonColor = inputClearButtonColor
|
||||||
|
@ -4,9 +4,8 @@ import TelegramCore
|
|||||||
|
|
||||||
public func textAlertController(context: AccountContext, title: String?, text: String, actions: [TextAlertAction], actionLayout: TextAlertContentActionLayout = .horizontal) -> AlertController {
|
public func textAlertController(context: AccountContext, title: String?, text: String, actions: [TextAlertAction], actionLayout: TextAlertContentActionLayout = .horizontal) -> AlertController {
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let theme = presentationData.theme
|
|
||||||
|
|
||||||
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationTheme: theme), title: title, text: text, actions: actions)
|
let controller = standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: title, text: text, actions: actions)
|
||||||
let presentationDataDisposable = context.sharedContext.presentationData.start(next: { [weak controller] presentationData in
|
let presentationDataDisposable = context.sharedContext.presentationData.start(next: { [weak controller] presentationData in
|
||||||
controller?.theme = AlertControllerTheme(presentationTheme: presentationData.theme)
|
controller?.theme = AlertControllerTheme(presentationTheme: presentationData.theme)
|
||||||
})
|
})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user