mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
89d2ad8cf6
commit
eb4519e192
@ -13008,6 +13008,8 @@ Sorry for the inconvenience.";
|
|||||||
"Gift.Options.Gift.Filter.AllGifts" = "All Gifts";
|
"Gift.Options.Gift.Filter.AllGifts" = "All Gifts";
|
||||||
"Gift.Options.Gift.Filter.Limited" = "Limited";
|
"Gift.Options.Gift.Filter.Limited" = "Limited";
|
||||||
"Gift.Options.Gift.Limited" = "Limited";
|
"Gift.Options.Gift.Limited" = "Limited";
|
||||||
|
"Gift.Options.Gift.SoldOut" = "Sold Out";
|
||||||
|
"Gift.Options.SoldOut.Text" = "Sorry, this gift is sold out.";
|
||||||
|
|
||||||
"PeerInfo.PaneGifts" = "Gifts";
|
"PeerInfo.PaneGifts" = "Gifts";
|
||||||
|
|
||||||
@ -13039,6 +13041,10 @@ Sorry for the inconvenience.";
|
|||||||
"Gift.Send.HideMyName.Info" = "Hide my name and message from visitors to %1$@'s profile. %2$@ will still see your name and message.";
|
"Gift.Send.HideMyName.Info" = "Hide my name and message from visitors to %1$@'s profile. %2$@ will still see your name and message.";
|
||||||
"Gift.Send.Send" = "Send a Gift for";
|
"Gift.Send.Send" = "Send a Gift for";
|
||||||
"Gift.Send.Limited" = "Limited";
|
"Gift.Send.Limited" = "Limited";
|
||||||
|
"Gift.Send.Left" = "left";
|
||||||
|
|
||||||
|
"Gift.Send.ErrorUnknown" = "An error occurred. Please try again.";
|
||||||
|
"Gift.Send.ErrorOutOfStock" = "Sorry, this gift is sold out. Please choose another gift.";
|
||||||
|
|
||||||
"Profile.SendGift" = "Send a Gift";
|
"Profile.SendGift" = "Send a Gift";
|
||||||
"Settings.SendGift" = "Send a Gift";
|
"Settings.SendGift" = "Send a Gift";
|
||||||
@ -13061,6 +13067,7 @@ Sorry for the inconvenience.";
|
|||||||
|
|
||||||
"Notification.PremiumGift.YearsTitle_1" = "%@ Year Premium";
|
"Notification.PremiumGift.YearsTitle_1" = "%@ Year Premium";
|
||||||
"Notification.PremiumGift.YearsTitle_any" = "%@ Years Premium";
|
"Notification.PremiumGift.YearsTitle_any" = "%@ Years Premium";
|
||||||
|
"Notification.PremiumGift.More" = "more";
|
||||||
|
|
||||||
"Notification.PremiumGift.SubscriptionDescription" = "Subscription for exclusive Telegram features.";
|
"Notification.PremiumGift.SubscriptionDescription" = "Subscription for exclusive Telegram features.";
|
||||||
|
|
||||||
|
@ -931,13 +931,13 @@ public final class AvatarNode: ASDisplayNode {
|
|||||||
if let repliesIcon = repliesIcon {
|
if let repliesIcon = repliesIcon {
|
||||||
context.draw(repliesIcon.cgImage!, in: CGRect(origin: CGPoint(x: floor((bounds.size.width - repliesIcon.size.width) / 2.0), y: floor((bounds.size.height - repliesIcon.size.height) / 2.0)), size: repliesIcon.size))
|
context.draw(repliesIcon.cgImage!, in: CGRect(origin: CGPoint(x: floor((bounds.size.width - repliesIcon.size.width) / 2.0), y: floor((bounds.size.height - repliesIcon.size.height) / 2.0)), size: repliesIcon.size))
|
||||||
}
|
}
|
||||||
} else if case .anonymousSavedMessagesIcon = parameters.icon {
|
} else if case let .anonymousSavedMessagesIcon(isColored) = parameters.icon {
|
||||||
let factor = bounds.size.width / 60.0
|
let factor = bounds.size.width / 60.0
|
||||||
context.translateBy(x: bounds.size.width / 2.0, y: bounds.size.height / 2.0)
|
context.translateBy(x: bounds.size.width / 2.0, y: bounds.size.height / 2.0)
|
||||||
context.scaleBy(x: factor, y: -factor)
|
context.scaleBy(x: factor, y: -factor)
|
||||||
context.translateBy(x: -bounds.size.width / 2.0, y: -bounds.size.height / 2.0)
|
context.translateBy(x: -bounds.size.width / 2.0, y: -bounds.size.height / 2.0)
|
||||||
|
|
||||||
if let theme = parameters.theme, theme.overallDarkAppearance {
|
if let theme = parameters.theme, theme.overallDarkAppearance, !isColored {
|
||||||
if let anonymousSavedMessagesDarkIcon = anonymousSavedMessagesDarkIcon {
|
if let anonymousSavedMessagesDarkIcon = anonymousSavedMessagesDarkIcon {
|
||||||
context.draw(anonymousSavedMessagesDarkIcon.cgImage!, in: CGRect(origin: CGPoint(x: floor((bounds.size.width - anonymousSavedMessagesDarkIcon.size.width) / 2.0), y: floor((bounds.size.height - anonymousSavedMessagesDarkIcon.size.height) / 2.0)), size: anonymousSavedMessagesDarkIcon.size))
|
context.draw(anonymousSavedMessagesDarkIcon.cgImage!, in: CGRect(origin: CGPoint(x: floor((bounds.size.width - anonymousSavedMessagesDarkIcon.size.width) / 2.0), y: floor((bounds.size.height - anonymousSavedMessagesDarkIcon.size.height) / 2.0)), size: anonymousSavedMessagesDarkIcon.size))
|
||||||
}
|
}
|
||||||
|
@ -1558,19 +1558,23 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
|||||||
applePayController.presentingViewController?.dismiss(animated: true, completion: nil)
|
applePayController.presentingViewController?.dismiss(animated: true, completion: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
let text: String
|
let text: String?
|
||||||
switch error {
|
switch error {
|
||||||
case .precheckoutFailed:
|
case .precheckoutFailed:
|
||||||
text = strongSelf.presentationData.strings.Checkout_ErrorPrecheckoutFailed
|
text = strongSelf.presentationData.strings.Checkout_ErrorPrecheckoutFailed
|
||||||
case .paymentFailed:
|
case .paymentFailed:
|
||||||
text = strongSelf.presentationData.strings.Checkout_ErrorPaymentFailed
|
text = strongSelf.presentationData.strings.Checkout_ErrorPaymentFailed
|
||||||
case .alreadyPaid:
|
case .alreadyPaid:
|
||||||
text = strongSelf.presentationData.strings.Checkout_ErrorInvoiceAlreadyPaid
|
text = strongSelf.presentationData.strings.Checkout_ErrorInvoiceAlreadyPaid
|
||||||
case .generic:
|
case .generic:
|
||||||
text = strongSelf.presentationData.strings.Checkout_ErrorGeneric
|
text = strongSelf.presentationData.strings.Checkout_ErrorGeneric
|
||||||
|
default:
|
||||||
|
text = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil)
|
if let text {
|
||||||
|
strongSelf.present(textAlertController(context: strongSelf.context, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
|
}
|
||||||
|
|
||||||
strongSelf.failed()
|
strongSelf.failed()
|
||||||
}
|
}
|
||||||
|
@ -588,6 +588,7 @@ public enum SendBotPaymentFormError {
|
|||||||
case precheckoutFailed
|
case precheckoutFailed
|
||||||
case paymentFailed
|
case paymentFailed
|
||||||
case alreadyPaid
|
case alreadyPaid
|
||||||
|
case starGiftOutOfStock
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum SendBotPaymentResult {
|
public enum SendBotPaymentResult {
|
||||||
@ -702,6 +703,8 @@ func _internal_sendBotPaymentForm(account: Account, formId: Int64, source: BotPa
|
|||||||
return .fail(.paymentFailed)
|
return .fail(.paymentFailed)
|
||||||
} else if error.errorDescription == "INVOICE_ALREADY_PAID" {
|
} else if error.errorDescription == "INVOICE_ALREADY_PAID" {
|
||||||
return .fail(.alreadyPaid)
|
return .fail(.alreadyPaid)
|
||||||
|
} else if error.errorDescription == "STARGIFT_USAGE_LIMITED" {
|
||||||
|
return .fail(.starGiftOutOfStock)
|
||||||
}
|
}
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
|
@ -6224,7 +6224,7 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||||||
}
|
}
|
||||||
|
|
||||||
for contentNode in self.contentNodes {
|
for contentNode in self.contentNodes {
|
||||||
if contentNode is ChatMessageMediaBubbleContentNode {
|
if contentNode is ChatMessageMediaBubbleContentNode || contentNode is ChatMessageGiftBubbleContentNode {
|
||||||
contentNode.visibility = mapVisibility(effectiveMediaVisibility, boundsSize: self.bounds.size, insets: self.insets, to: contentNode)
|
contentNode.visibility = mapVisibility(effectiveMediaVisibility, boundsSize: self.bounds.size, insets: self.insets, to: contentNode)
|
||||||
} else {
|
} else {
|
||||||
contentNode.visibility = mapVisibility(effectiveVisibility, boundsSize: self.bounds.size, insets: self.insets, to: contentNode)
|
contentNode.visibility = mapVisibility(effectiveVisibility, boundsSize: self.bounds.size, insets: self.insets, to: contentNode)
|
||||||
|
@ -50,6 +50,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
private let buttonStarsNode: PremiumStarsNode
|
private let buttonStarsNode: PremiumStarsNode
|
||||||
private let buttonTitleNode: TextNode
|
private let buttonTitleNode: TextNode
|
||||||
|
|
||||||
|
private let moreTextNode: TextNode
|
||||||
|
|
||||||
private var maskView: UIImageView?
|
private var maskView: UIImageView?
|
||||||
private var maskOverlayView: UIView?
|
private var maskOverlayView: UIView?
|
||||||
|
|
||||||
@ -61,6 +63,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
private var isExpanded: Bool = false
|
private var isExpanded: Bool = false
|
||||||
private var appliedIsExpanded: Bool = false
|
private var appliedIsExpanded: Bool = false
|
||||||
|
|
||||||
|
private var isStarGift = false
|
||||||
|
|
||||||
private var currentProgressDisposable: Disposable?
|
private var currentProgressDisposable: Disposable?
|
||||||
|
|
||||||
override public var visibility: ListViewItemNodeVisibility {
|
override public var visibility: ListViewItemNodeVisibility {
|
||||||
@ -138,6 +142,10 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
self.ribbonTextNode.isUserInteractionEnabled = false
|
self.ribbonTextNode.isUserInteractionEnabled = false
|
||||||
self.ribbonTextNode.displaysAsynchronously = false
|
self.ribbonTextNode.displaysAsynchronously = false
|
||||||
|
|
||||||
|
self.moreTextNode = TextNode()
|
||||||
|
self.moreTextNode.isUserInteractionEnabled = false
|
||||||
|
self.moreTextNode.displaysAsynchronously = false
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.addSubnode(self.labelNode)
|
self.addSubnode(self.labelNode)
|
||||||
@ -147,6 +155,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
self.textClippingNode.addSubnode(self.subtitleNode.textNode)
|
self.textClippingNode.addSubnode(self.subtitleNode.textNode)
|
||||||
self.addSubnode(self.placeholderNode)
|
self.addSubnode(self.placeholderNode)
|
||||||
self.addSubnode(self.animationNode)
|
self.addSubnode(self.animationNode)
|
||||||
|
self.addSubnode(self.moreTextNode)
|
||||||
|
|
||||||
self.addSubnode(self.buttonNode)
|
self.addSubnode(self.buttonNode)
|
||||||
self.buttonNode.addSubnode(self.buttonStarsNode)
|
self.buttonNode.addSubnode(self.buttonStarsNode)
|
||||||
@ -183,6 +192,19 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
self.currentProgressDisposable?.dispose()
|
self.currentProgressDisposable?.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override public func didLoad() {
|
||||||
|
super.didLoad()
|
||||||
|
|
||||||
|
self.maskView = UIImageView()
|
||||||
|
|
||||||
|
let maskOverlayView = UIView()
|
||||||
|
maskOverlayView.alpha = 0.0
|
||||||
|
maskOverlayView.backgroundColor = .white
|
||||||
|
self.maskOverlayView = maskOverlayView
|
||||||
|
|
||||||
|
self.maskView?.addSubview(maskOverlayView)
|
||||||
|
}
|
||||||
|
|
||||||
@objc private func buttonPressed() {
|
@objc private func buttonPressed() {
|
||||||
guard let item = self.item else {
|
guard let item = self.item else {
|
||||||
return
|
return
|
||||||
@ -190,6 +212,14 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default, progress: self.makeProgress()))
|
let _ = item.controllerInteraction.openMessage(item.message, OpenMessageParams(mode: .default, progress: self.makeProgress()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func expandPressed() {
|
||||||
|
self.isExpanded = !self.isExpanded
|
||||||
|
guard let item = self.item else{
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let _ = item.controllerInteraction.requestMessageUpdate(item.message.id, false)
|
||||||
|
}
|
||||||
|
|
||||||
private func makeProgress() -> Promise<Bool> {
|
private func makeProgress() -> Promise<Bool> {
|
||||||
let progress = Promise<Bool>()
|
let progress = Promise<Bool>()
|
||||||
self.currentProgressDisposable?.dispose()
|
self.currentProgressDisposable?.dispose()
|
||||||
@ -263,6 +293,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
let makeButtonTitleLayout = TextNode.asyncLayout(self.buttonTitleNode)
|
let makeButtonTitleLayout = TextNode.asyncLayout(self.buttonTitleNode)
|
||||||
let makeRibbonTextLayout = TextNode.asyncLayout(self.ribbonTextNode)
|
let makeRibbonTextLayout = TextNode.asyncLayout(self.ribbonTextNode)
|
||||||
let makeMeasureTextLayout = TextNode.asyncLayout(nil)
|
let makeMeasureTextLayout = TextNode.asyncLayout(nil)
|
||||||
|
let makeMoreTextLayout = TextNode.asyncLayout(self.moreTextNode)
|
||||||
|
|
||||||
let cachedMaskBackgroundImage = self.cachedMaskBackgroundImage
|
let cachedMaskBackgroundImage = self.cachedMaskBackgroundImage
|
||||||
|
|
||||||
@ -290,6 +321,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
var ribbonTitle = ""
|
var ribbonTitle = ""
|
||||||
var hasServiceMessage = true
|
var hasServiceMessage = true
|
||||||
var textSpacing: CGFloat = 0.0
|
var textSpacing: CGFloat = 0.0
|
||||||
|
var isStarGift = false
|
||||||
for media in item.message.media {
|
for media in item.message.media {
|
||||||
if let action = media as? TelegramMediaAction {
|
if let action = media as? TelegramMediaAction {
|
||||||
switch action.action {
|
switch action.action {
|
||||||
@ -377,6 +409,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
hasServiceMessage = false
|
hasServiceMessage = false
|
||||||
}
|
}
|
||||||
case let .starGift(gift, convertStars, giftText, giftEntities, _, savedToProfile, converted):
|
case let .starGift(gift, convertStars, giftText, giftEntities, _, savedToProfile, converted):
|
||||||
|
isStarGift = true
|
||||||
let authorName = item.message.author.flatMap { EnginePeer($0) }?.compactDisplayTitle ?? ""
|
let authorName = item.message.author.flatMap { EnginePeer($0) }?.compactDisplayTitle ?? ""
|
||||||
title = item.presentationData.strings.Notification_StarGift_Title(authorName).string
|
title = item.presentationData.strings.Notification_StarGift_Title(authorName).string
|
||||||
if let giftText, !giftText.isEmpty {
|
if let giftText, !giftText.isEmpty {
|
||||||
@ -439,8 +472,10 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
|
|
||||||
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
|
let (moreLayout, moreApply) = makeMoreTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Notification_PremiumGift_More, font: Font.semibold(13.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
let attributedText: NSAttributedString
|
let attributedText: NSAttributedString
|
||||||
if let _ = animationFile {
|
if !entities.isEmpty {
|
||||||
attributedText = stringWithAppliedEntities(text, entities: entities, baseColor: primaryTextColor, linkColor: primaryTextColor, baseFont: Font.regular(13.0), linkFont: Font.regular(13.0), boldFont: Font.semibold(13.0), italicFont: Font.italic(13.0), boldItalicFont: Font.semiboldItalic(13.0), fixedFont: Font.monospace(13.0), blockQuoteFont: Font.regular(13.0), message: nil)
|
attributedText = stringWithAppliedEntities(text, entities: entities, baseColor: primaryTextColor, linkColor: primaryTextColor, baseFont: Font.regular(13.0), linkFont: Font.regular(13.0), boldFont: Font.semibold(13.0), italicFont: Font.italic(13.0), boldItalicFont: Font.semiboldItalic(13.0), fixedFont: Font.monospace(13.0), blockQuoteFont: Font.regular(13.0), message: nil)
|
||||||
} else {
|
} else {
|
||||||
attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(
|
attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(
|
||||||
@ -578,6 +613,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
strongSelf.item = item
|
strongSelf.item = item
|
||||||
|
strongSelf.isStarGift = isStarGift
|
||||||
|
|
||||||
strongSelf.updateVisibility()
|
strongSelf.updateVisibility()
|
||||||
|
|
||||||
@ -599,6 +635,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
))
|
))
|
||||||
let _ = buttonTitleApply()
|
let _ = buttonTitleApply()
|
||||||
let _ = ribbonTextApply()
|
let _ = ribbonTextApply()
|
||||||
|
let _ = moreApply()
|
||||||
|
|
||||||
let labelFrame = CGRect(origin: CGPoint(x: 8.0, y: 2.0), size: labelLayout.size)
|
let labelFrame = CGRect(origin: CGPoint(x: 8.0, y: 2.0), size: labelLayout.size)
|
||||||
strongSelf.labelNode.frame = labelFrame
|
strongSelf.labelNode.frame = labelFrame
|
||||||
@ -606,7 +643,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
let titleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - titleLayout.size.width) / 2.0) , y: mediaBackgroundFrame.minY + 151.0), size: titleLayout.size)
|
let titleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - titleLayout.size.width) / 2.0) , y: mediaBackgroundFrame.minY + 151.0), size: titleLayout.size)
|
||||||
strongSelf.titleNode.frame = titleFrame
|
strongSelf.titleNode.frame = titleFrame
|
||||||
|
|
||||||
let clippingTextFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - subtitleLayout.size.width) / 2.0) , y: titleFrame.maxY + textSpacing), size: CGSize(width: boundingWidth, height: clippedTextHeight))
|
let clippingTextFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - subtitleLayout.size.width) / 2.0) , y: titleFrame.maxY + textSpacing), size: CGSize(width: subtitleLayout.size.width, height: clippedTextHeight))
|
||||||
|
|
||||||
let subtitleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - subtitleLayout.size.width) / 2.0) , y: titleFrame.maxY + textSpacing), size: subtitleLayout.size)
|
let subtitleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - subtitleLayout.size.width) / 2.0) , y: titleFrame.maxY + textSpacing), size: subtitleLayout.size)
|
||||||
strongSelf.subtitleNode.textNode.frame = CGRect(origin: .zero, size: subtitleLayout.size)
|
strongSelf.subtitleNode.textNode.frame = CGRect(origin: .zero, size: subtitleLayout.size)
|
||||||
@ -617,10 +654,10 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
animation.animator.updateFrame(layer: strongSelf.textClippingNode.layer, frame: clippingTextFrame, completion: nil)
|
animation.animator.updateFrame(layer: strongSelf.textClippingNode.layer, frame: clippingTextFrame, completion: nil)
|
||||||
}
|
}
|
||||||
if let maskView = strongSelf.maskView, let maskOverlayView = strongSelf.maskOverlayView {
|
if let maskView = strongSelf.maskView, let maskOverlayView = strongSelf.maskOverlayView {
|
||||||
animation.animator.updateFrame(layer: maskView.layer, frame: CGRect(origin: .zero, size: CGSize(width: boundingWidth, height: clippingTextFrame.size.height)), completion: nil)
|
animation.animator.updateFrame(layer: maskView.layer, frame: CGRect(origin: .zero, size: CGSize(width: clippingTextFrame.width, height: clippingTextFrame.height)), completion: nil)
|
||||||
animation.animator.updateFrame(layer: maskOverlayView.layer, frame: CGRect(origin: .zero, size: CGSize(width: boundingWidth, height: clippingTextFrame.size.height)), completion: nil)
|
animation.animator.updateFrame(layer: maskOverlayView.layer, frame: CGRect(origin: .zero, size: CGSize(width: clippingTextFrame.width, height: clippingTextFrame.height)), completion: nil)
|
||||||
}
|
}
|
||||||
|
animation.animator.updateFrame(layer: strongSelf.moreTextNode.layer, frame: CGRect(origin: CGPoint(x: clippingTextFrame.maxX - moreLayout.size.width, y: clippingTextFrame.maxY - moreLayout.size.height), size: moreLayout.size), completion: nil)
|
||||||
|
|
||||||
if !subtitleLayout.spoilers.isEmpty {
|
if !subtitleLayout.spoilers.isEmpty {
|
||||||
let dustColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper).primaryText
|
let dustColor = serviceMessageColorComponents(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper).primaryText
|
||||||
@ -734,24 +771,16 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
strongSelf.updateAbsoluteRect(rect, within: size)
|
strongSelf.updateAbsoluteRect(rect, within: size)
|
||||||
}
|
}
|
||||||
|
|
||||||
if canExpand {
|
if canExpand, let maskView = strongSelf.maskView {
|
||||||
if strongSelf.maskView?.image == nil {
|
if maskView.image == nil {
|
||||||
strongSelf.maskView?.image = generateMaskImage()
|
maskView.image = generateMaskImage()
|
||||||
}
|
}
|
||||||
strongSelf.textClippingNode.view.mask = strongSelf.maskView
|
strongSelf.textClippingNode.view.mask = strongSelf.maskView
|
||||||
|
|
||||||
// var expandIconFrame: CGRect = .zero
|
animation.animator.updateAlpha(layer: strongSelf.moreTextNode.layer, alpha: strongSelf.isExpanded ? 0.0 : 1.0, completion: nil)
|
||||||
// if let icon = strongSelf.expandIcon.image {
|
|
||||||
// expandIconFrame = CGRect(origin: CGPoint(x: boundingWidth - icon.size.width - 19.0, y: backgroundFrame.maxY - icon.size.height - 6.0), size: icon.size)
|
|
||||||
// if wasHidden || isFirstTime {
|
|
||||||
// strongSelf.expandIcon.position = expandIconFrame.center
|
|
||||||
// } else {
|
|
||||||
// animation.animator.updatePosition(layer: strongSelf.expandIcon.layer, position: expandIconFrame.center, completion: nil)
|
|
||||||
// }
|
|
||||||
// strongSelf.expandIcon.bounds = CGRect(origin: .zero, size: expandIconFrame.size)
|
|
||||||
// }
|
|
||||||
} else {
|
} else {
|
||||||
strongSelf.textClippingNode.view.mask = nil
|
strongSelf.textClippingNode.view.mask = nil
|
||||||
|
strongSelf.moreTextNode.alpha = 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
switch strongSelf.visibility {
|
switch strongSelf.visibility {
|
||||||
@ -876,6 +905,9 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
|
|
||||||
if self.buttonNode.frame.contains(point) {
|
if self.buttonNode.frame.contains(point) {
|
||||||
return ChatMessageBubbleContentTapAction(content: .ignore)
|
return ChatMessageBubbleContentTapAction(content: .ignore)
|
||||||
|
} else if self.textClippingNode.frame.contains(point) && !self.isExpanded && !self.moreTextNode.alpha.isZero {
|
||||||
|
self.expandPressed()
|
||||||
|
return ChatMessageBubbleContentTapAction(content: .ignore)
|
||||||
} else if let backgroundNode = self.backgroundNode, backgroundNode.frame.contains(point) {
|
} else if let backgroundNode = self.backgroundNode, backgroundNode.frame.contains(point) {
|
||||||
return ChatMessageBubbleContentTapAction(content: .openMessage)
|
return ChatMessageBubbleContentTapAction(content: .openMessage)
|
||||||
} else if self.mediaBackgroundContent?.frame.contains(point) == true {
|
} else if self.mediaBackgroundContent?.frame.contains(point) == true {
|
||||||
@ -934,7 +966,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
|
|
||||||
if !alreadySeen && self.animationNode.isPlaying {
|
if !alreadySeen && self.animationNode.isPlaying {
|
||||||
item.controllerInteraction.playNextOutgoingGift = false
|
item.controllerInteraction.playNextOutgoingGift = false
|
||||||
Queue.mainQueue().after(1.0) {
|
|
||||||
|
Queue.mainQueue().after(self.isStarGift ? 0.1 : 1.0) {
|
||||||
item.controllerInteraction.animateDiceSuccess(false, true)
|
item.controllerInteraction.animateDiceSuccess(false, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -943,7 +976,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func generateMaskImage() -> UIImage? {
|
private func generateMaskImage() -> UIImage? {
|
||||||
return generateImage(CGSize(width: 140, height: 30), rotatedContext: { size, context in
|
return generateImage(CGSize(width: 100.0, height: 30.0), rotatedContext: { size, context in
|
||||||
context.clear(CGRect(origin: .zero, size: size))
|
context.clear(CGRect(origin: .zero, size: size))
|
||||||
|
|
||||||
context.setFillColor(UIColor.white.cgColor)
|
context.setFillColor(UIColor.white.cgColor)
|
||||||
@ -956,7 +989,7 @@ private func generateMaskImage() -> UIImage? {
|
|||||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
||||||
|
|
||||||
context.setBlendMode(.copy)
|
context.setBlendMode(.copy)
|
||||||
context.clip(to: CGRect(origin: CGPoint(x: 10.0, y: 8.0), size: CGSize(width: 130.0, height: 22.0)))
|
context.clip(to: CGRect(origin: CGPoint(x: 10.0, y: 12.0), size: CGSize(width: 130.0, height: 18.0)))
|
||||||
context.drawLinearGradient(gradient, start: CGPoint(x: 10.0, y: 0.0), end: CGPoint(x: size.width, y: 0.0), options: CGGradientDrawingOptions())
|
context.drawLinearGradient(gradient, start: CGPoint(x: 30.0, y: 0.0), end: CGPoint(x: size.width, y: 0.0), options: CGGradientDrawingOptions())
|
||||||
})?.resizableImage(withCapInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 22.0, right: 130.0))
|
})?.resizableImage(withCapInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 18.0, right: 70.0))
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ public final class GiftItemComponent: Component {
|
|||||||
let ribbon: Ribbon?
|
let ribbon: Ribbon?
|
||||||
let isLoading: Bool
|
let isLoading: Bool
|
||||||
let isHidden: Bool
|
let isHidden: Bool
|
||||||
|
let isSoldOut: Bool
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
context: AccountContext,
|
context: AccountContext,
|
||||||
@ -75,7 +76,8 @@ public final class GiftItemComponent: Component {
|
|||||||
price: String,
|
price: String,
|
||||||
ribbon: Ribbon? = nil,
|
ribbon: Ribbon? = nil,
|
||||||
isLoading: Bool = false,
|
isLoading: Bool = false,
|
||||||
isHidden: Bool = false
|
isHidden: Bool = false,
|
||||||
|
isSoldOut: Bool = false
|
||||||
) {
|
) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
@ -87,6 +89,7 @@ public final class GiftItemComponent: Component {
|
|||||||
self.ribbon = ribbon
|
self.ribbon = ribbon
|
||||||
self.isLoading = isLoading
|
self.isLoading = isLoading
|
||||||
self.isHidden = isHidden
|
self.isHidden = isHidden
|
||||||
|
self.isSoldOut = isSoldOut
|
||||||
}
|
}
|
||||||
|
|
||||||
public static func ==(lhs: GiftItemComponent, rhs: GiftItemComponent) -> Bool {
|
public static func ==(lhs: GiftItemComponent, rhs: GiftItemComponent) -> Bool {
|
||||||
@ -120,6 +123,9 @@ public final class GiftItemComponent: Component {
|
|||||||
if lhs.isHidden != rhs.isHidden {
|
if lhs.isHidden != rhs.isHidden {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.isSoldOut != rhs.isSoldOut {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,14 +290,26 @@ public final class GiftItemComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let buttonColor: UIColor
|
||||||
|
var isStars = false
|
||||||
|
if component.isSoldOut {
|
||||||
|
buttonColor = component.theme.list.itemDestructiveColor
|
||||||
|
} else if component.price.containsEmoji {
|
||||||
|
buttonColor = UIColor(rgb: 0xd3720a)
|
||||||
|
isStars = true
|
||||||
|
} else {
|
||||||
|
buttonColor = component.theme.list.itemAccentColor
|
||||||
|
}
|
||||||
|
|
||||||
let buttonSize = self.button.update(
|
let buttonSize = self.button.update(
|
||||||
transition: transition,
|
transition: transition,
|
||||||
component: AnyComponent(
|
component: AnyComponent(
|
||||||
ButtonContentComponent(
|
ButtonContentComponent(
|
||||||
context: component.context,
|
context: component.context,
|
||||||
text: component.price,
|
text: component.price,
|
||||||
color: component.price.containsEmoji ? UIColor(rgb: 0xd3720a) : component.theme.list.itemAccentColor,
|
color: buttonColor,
|
||||||
isStars: component.price.containsEmoji)
|
isStars: isStars
|
||||||
|
)
|
||||||
),
|
),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: availableSize
|
containerSize: availableSize
|
||||||
|
@ -25,6 +25,7 @@ import GiftItemComponent
|
|||||||
import InAppPurchaseManager
|
import InAppPurchaseManager
|
||||||
import TabSelectorComponent
|
import TabSelectorComponent
|
||||||
import GiftSetupScreen
|
import GiftSetupScreen
|
||||||
|
import UndoUI
|
||||||
|
|
||||||
final class GiftOptionsScreenComponent: Component {
|
final class GiftOptionsScreenComponent: Component {
|
||||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||||
@ -173,6 +174,20 @@ final class GiftOptionsScreenComponent: Component {
|
|||||||
self.updateScrolling(transition: .immediate)
|
self.updateScrolling(transition: .immediate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func dismissAllTooltips(controller: ViewController) {
|
||||||
|
controller.forEachController({ controller in
|
||||||
|
if let controller = controller as? UndoOverlayController {
|
||||||
|
controller.dismissWithCommitAction()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
controller.window?.forEachController({ controller in
|
||||||
|
if let controller = controller as? UndoOverlayController {
|
||||||
|
controller.dismissWithCommitAction()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private func updateScrolling(transition: ComponentTransition) {
|
private func updateScrolling(transition: ComponentTransition) {
|
||||||
guard let environment = self.environment, let component = self.component else {
|
guard let environment = self.environment, let component = self.component else {
|
||||||
return
|
return
|
||||||
@ -274,6 +289,7 @@ final class GiftOptionsScreenComponent: Component {
|
|||||||
self.starsItems[itemId] = visibleItem
|
self.starsItems[itemId] = visibleItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let isSoldOut = gift.availability?.remains == 0
|
||||||
let _ = visibleItem.update(
|
let _ = visibleItem.update(
|
||||||
transition: itemTransition,
|
transition: itemTransition,
|
||||||
component: AnyComponent(
|
component: AnyComponent(
|
||||||
@ -284,13 +300,14 @@ final class GiftOptionsScreenComponent: Component {
|
|||||||
theme: environment.theme,
|
theme: environment.theme,
|
||||||
peer: nil,
|
peer: nil,
|
||||||
subject: .starGift(gift.id, gift.file),
|
subject: .starGift(gift.id, gift.file),
|
||||||
price: "⭐️ \(gift.price)",
|
price: isSoldOut ? environment.strings.Gift_Options_Gift_SoldOut : "⭐️ \(gift.price)",
|
||||||
ribbon: gift.availability != nil ?
|
ribbon: gift.availability != nil ?
|
||||||
GiftItemComponent.Ribbon(
|
GiftItemComponent.Ribbon(
|
||||||
text: environment.strings.Gift_Options_Gift_Limited,
|
text: environment.strings.Gift_Options_Gift_Limited,
|
||||||
color: .blue
|
color: .blue
|
||||||
)
|
)
|
||||||
: nil
|
: nil,
|
||||||
|
isSoldOut: isSoldOut
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
effectAlignment: .center,
|
effectAlignment: .center,
|
||||||
@ -303,13 +320,25 @@ final class GiftOptionsScreenComponent: Component {
|
|||||||
} else {
|
} else {
|
||||||
mainController = controller
|
mainController = controller
|
||||||
}
|
}
|
||||||
let giftController = GiftSetupScreen(
|
if gift.availability?.remains == 0 {
|
||||||
context: component.context,
|
self.dismissAllTooltips(controller: mainController)
|
||||||
peerId: component.peerId,
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
subject: .starGift(gift),
|
let resultController = UndoOverlayController(
|
||||||
completion: component.completion
|
presentationData: presentationData,
|
||||||
)
|
content: .sticker(context: component.context, file: gift.file, loop: false, title: nil, text: presentationData.strings.Gift_Options_SoldOut_Text, undoText: nil, customAction: nil),
|
||||||
mainController.push(giftController)
|
elevatedLayout: false,
|
||||||
|
action: { _ in return true }
|
||||||
|
)
|
||||||
|
mainController.present(resultController, in: .window(.root))
|
||||||
|
} else {
|
||||||
|
let giftController = GiftSetupScreen(
|
||||||
|
context: component.context,
|
||||||
|
peerId: component.peerId,
|
||||||
|
subject: .starGift(gift),
|
||||||
|
completion: component.completion
|
||||||
|
)
|
||||||
|
mainController.push(giftController)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -43,6 +43,7 @@ swift_library(
|
|||||||
"//submodules/TelegramUI/Components/EmojiSuggestionsComponent",
|
"//submodules/TelegramUI/Components/EmojiSuggestionsComponent",
|
||||||
"//submodules/TelegramUI/Components/ChatEntityKeyboardInputNode",
|
"//submodules/TelegramUI/Components/ChatEntityKeyboardInputNode",
|
||||||
"//submodules/InAppPurchaseManager",
|
"//submodules/InAppPurchaseManager",
|
||||||
|
"//submodules/Components/BlurredBackgroundComponent",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -258,7 +258,7 @@ final class ChatGiftPreviewItemNode: ListViewItemNode {
|
|||||||
apply().1(ListViewItemApply(isOnScreen: true))
|
apply().1(ListViewItemApply(isOnScreen: true))
|
||||||
})
|
})
|
||||||
itemNode!.isUserInteractionEnabled = false
|
itemNode!.isUserInteractionEnabled = false
|
||||||
itemNode?.visibility = .visible(1.0, .infinite)
|
itemNode!.visibility = .visible(1.0, .infinite)
|
||||||
messageNodes.append(itemNode!)
|
messageNodes.append(itemNode!)
|
||||||
|
|
||||||
self.initialBubbleHeight = itemNode?.frame.height
|
self.initialBubbleHeight = itemNode?.frame.height
|
||||||
|
@ -29,6 +29,7 @@ import ChatPresentationInterfaceState
|
|||||||
import AudioToolbox
|
import AudioToolbox
|
||||||
import TextFormat
|
import TextFormat
|
||||||
import InAppPurchaseManager
|
import InAppPurchaseManager
|
||||||
|
import BlurredBackgroundComponent
|
||||||
|
|
||||||
final class GiftSetupScreenComponent: Component {
|
final class GiftSetupScreenComponent: Component {
|
||||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||||
@ -78,6 +79,9 @@ final class GiftSetupScreenComponent: Component {
|
|||||||
private let introContent = ComponentView<Empty>()
|
private let introContent = ComponentView<Empty>()
|
||||||
private let introSection = ComponentView<Empty>()
|
private let introSection = ComponentView<Empty>()
|
||||||
private let hideSection = ComponentView<Empty>()
|
private let hideSection = ComponentView<Empty>()
|
||||||
|
|
||||||
|
private let buttonBackground = ComponentView<Empty>()
|
||||||
|
private let buttonSeparator = SimpleLayer()
|
||||||
private let button = ComponentView<Empty>()
|
private let button = ComponentView<Empty>()
|
||||||
|
|
||||||
private var ignoreScrolling: Bool = false
|
private var ignoreScrolling: Bool = false
|
||||||
@ -356,6 +360,27 @@ final class GiftSetupScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
starsContext.load(force: true)
|
starsContext.load(force: true)
|
||||||
|
}, error: { [weak self] error in
|
||||||
|
guard let self, let controller = self.environment?.controller() else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.inProgress = false
|
||||||
|
self.state?.updated()
|
||||||
|
|
||||||
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
var errorText: String?
|
||||||
|
switch error {
|
||||||
|
case .starGiftOutOfStock:
|
||||||
|
errorText = presentationData.strings.Gift_Send_ErrorOutOfStock
|
||||||
|
default:
|
||||||
|
errorText = presentationData.strings.Gift_Send_ErrorUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
if let errorText = errorText {
|
||||||
|
let alertController = textAlertController(context: component.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
|
||||||
|
controller.present(alertController, in: .window(.root))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -826,6 +851,34 @@ final class GiftSetupScreenComponent: Component {
|
|||||||
self.starImage = (generateTintedImage(image: UIImage(bundleImageName: "Item List/PremiumIcon"), color: environment.theme.list.itemCheckColors.foregroundColor)!, environment.theme)
|
self.starImage = (generateTintedImage(image: UIImage(bundleImageName: "Item List/PremiumIcon"), color: environment.theme.list.itemCheckColors.foregroundColor)!, environment.theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let buttonHeight: CGFloat = 50.0
|
||||||
|
let bottomPanelPadding: CGFloat = 12.0
|
||||||
|
let bottomInset: CGFloat = environment.safeInsets.bottom > 0.0 ? environment.safeInsets.bottom + 5.0 : bottomPanelPadding
|
||||||
|
let bottomPanelHeight = bottomPanelPadding + buttonHeight + bottomInset
|
||||||
|
|
||||||
|
let bottomPanelAlpha: CGFloat = 1.0
|
||||||
|
let bottomPanelSize = self.buttonBackground.update(
|
||||||
|
transition: transition,
|
||||||
|
component: AnyComponent(BlurredBackgroundComponent(
|
||||||
|
color: environment.theme.rootController.tabBar.backgroundColor
|
||||||
|
)),
|
||||||
|
environment: {},
|
||||||
|
containerSize: CGSize(width: availableSize.width, height: bottomPanelHeight)
|
||||||
|
)
|
||||||
|
self.buttonSeparator.backgroundColor = environment.theme.rootController.tabBar.separatorColor.cgColor
|
||||||
|
self.buttonSeparator.opacity = Float(bottomPanelAlpha)
|
||||||
|
|
||||||
|
if let view = self.buttonBackground.view {
|
||||||
|
if view.superview == nil {
|
||||||
|
self.addSubview(view)
|
||||||
|
self.layer.addSublayer(self.buttonSeparator)
|
||||||
|
}
|
||||||
|
view.alpha = bottomPanelAlpha
|
||||||
|
view.frame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - bottomPanelSize.height), size: bottomPanelSize)
|
||||||
|
self.buttonSeparator.frame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - bottomPanelSize.height), size: CGSize(width: availableSize.width, height: UIScreenPixel))
|
||||||
|
}
|
||||||
|
|
||||||
|
var buttonIsEnabled = true
|
||||||
let buttonString: String
|
let buttonString: String
|
||||||
switch component.subject {
|
switch component.subject {
|
||||||
case let .premium(product):
|
case let .premium(product):
|
||||||
@ -834,6 +887,9 @@ final class GiftSetupScreenComponent: Component {
|
|||||||
case let .starGift(starGift):
|
case let .starGift(starGift):
|
||||||
let amountString = presentationStringsFormattedNumber(Int32(starGift.price), presentationData.dateTimeFormat.groupingSeparator)
|
let amountString = presentationStringsFormattedNumber(Int32(starGift.price), presentationData.dateTimeFormat.groupingSeparator)
|
||||||
buttonString = "\(environment.strings.Gift_Send_Send) # \(amountString)"
|
buttonString = "\(environment.strings.Gift_Send_Send) # \(amountString)"
|
||||||
|
if let availability = starGift.availability, availability.remains == 0 {
|
||||||
|
buttonIsEnabled = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let buttonAttributedString = NSMutableAttributedString(string: buttonString, font: Font.semibold(17.0), textColor: environment.theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center)
|
let buttonAttributedString = NSMutableAttributedString(string: buttonString, font: Font.semibold(17.0), textColor: environment.theme.list.itemCheckColors.foregroundColor, paragraphAlignment: .center)
|
||||||
@ -856,20 +912,20 @@ final class GiftSetupScreenComponent: Component {
|
|||||||
id: AnyHashable(0),
|
id: AnyHashable(0),
|
||||||
component: AnyComponent(MultilineTextComponent(text: .plain(buttonAttributedString)))
|
component: AnyComponent(MultilineTextComponent(text: .plain(buttonAttributedString)))
|
||||||
),
|
),
|
||||||
isEnabled: true,
|
isEnabled: buttonIsEnabled,
|
||||||
displaysProgress: self.inProgress,
|
displaysProgress: self.inProgress,
|
||||||
action: { [weak self] in
|
action: { [weak self] in
|
||||||
self?.proceed()
|
self?.proceed()
|
||||||
}
|
}
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 50)
|
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: buttonHeight)
|
||||||
)
|
)
|
||||||
if let buttonView = self.button.view {
|
if let buttonView = self.button.view {
|
||||||
if buttonView.superview == nil {
|
if buttonView.superview == nil {
|
||||||
self.addSubview(buttonView)
|
self.addSubview(buttonView)
|
||||||
}
|
}
|
||||||
buttonView.frame = CGRect(origin: CGPoint(x: floor((availableSize.width - buttonSize.width) / 2.0), y: availableSize.height - environment.safeInsets.bottom - buttonSize.height), size: buttonSize)
|
buttonView.frame = CGRect(origin: CGPoint(x: floor((availableSize.width - buttonSize.width) / 2.0), y: availableSize.height - bottomPanelHeight + bottomPanelPadding), size: buttonSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.textInputState.isEditing, let emojiSuggestion = self.textInputState.currentEmojiSuggestion, emojiSuggestion.disposable == nil {
|
if self.textInputState.isEditing, let emojiSuggestion = self.textInputState.currentEmojiSuggestion, emojiSuggestion.disposable == nil {
|
||||||
|
@ -119,6 +119,7 @@ public class RemainingCountComponent: Component {
|
|||||||
|
|
||||||
private let badgeForeground: SimpleLayer
|
private let badgeForeground: SimpleLayer
|
||||||
private let badgeLabel: BadgeLabelView
|
private let badgeLabel: BadgeLabelView
|
||||||
|
private let badgeLeftLabel = ComponentView<Empty>()
|
||||||
private let badgeLabelMaskView = UIImageView()
|
private let badgeLabelMaskView = UIImageView()
|
||||||
|
|
||||||
private var badgeTailPosition: CGFloat = 0.0
|
private var badgeTailPosition: CGFloat = 0.0
|
||||||
@ -737,7 +738,6 @@ final class BadgeLabelView: UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private var itemViews: [Int: StackView] = [:]
|
private var itemViews: [Int: StackView] = [:]
|
||||||
private var staticLabel = UILabel()
|
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
@ -752,7 +752,6 @@ final class BadgeLabelView: UIView {
|
|||||||
|
|
||||||
var color: UIColor = .white {
|
var color: UIColor = .white {
|
||||||
didSet {
|
didSet {
|
||||||
self.staticLabel.textColor = self.color
|
|
||||||
for (_, view) in self.itemViews {
|
for (_, view) in self.itemViews {
|
||||||
view.color = self.color
|
view.color = self.color
|
||||||
}
|
}
|
||||||
@ -760,25 +759,6 @@ final class BadgeLabelView: UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func update(value: String, transition: ComponentTransition) -> CGSize {
|
func update(value: String, transition: ComponentTransition) -> CGSize {
|
||||||
if value.contains(" ") {
|
|
||||||
for (_, view) in self.itemViews {
|
|
||||||
view.isHidden = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.staticLabel.superview == nil {
|
|
||||||
self.staticLabel.textColor = self.color
|
|
||||||
self.staticLabel.font = font
|
|
||||||
|
|
||||||
self.addSubview(self.staticLabel)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.staticLabel.text = value
|
|
||||||
let size = self.staticLabel.sizeThatFits(CGSize(width: 100.0, height: 100.0))
|
|
||||||
self.staticLabel.frame = CGRect(origin: .zero, size: CGSize(width: size.width, height: labelHeight))
|
|
||||||
|
|
||||||
return CGSize(width: ceil(self.staticLabel.bounds.width), height: ceil(self.staticLabel.bounds.height))
|
|
||||||
}
|
|
||||||
|
|
||||||
let string = value
|
let string = value
|
||||||
let stringArray = Array(string.map { String($0) }.reversed())
|
let stringArray = Array(string.map { String($0) }.reversed())
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user