mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
d7f7eefd4b
commit
3ef498d39a
@ -1045,6 +1045,7 @@ public protocol SharedAccountContext: AnyObject {
|
||||
func makeStarsPurchaseScreen(context: AccountContext, starsContext: StarsContext, options: [StarsTopUpOption], peerId: EnginePeer.Id?, requiredStars: Int64?, completion: @escaping (Int64) -> Void) -> ViewController
|
||||
func makeStarsTransferScreen(context: AccountContext, starsContext: StarsContext, invoice: TelegramMediaInvoice, source: BotPaymentInvoiceSource, inputData: Signal<(StarsContext.State, BotPaymentForm, EnginePeer?)?, NoError>) -> ViewController
|
||||
func makeStarsTransactionScreen(context: AccountContext, transaction: StarsContext.State.Transaction) -> ViewController
|
||||
func makeStarsReceiptScreen(context: AccountContext, receipt: BotPaymentReceipt, id: String?, date: Int32) -> ViewController
|
||||
|
||||
func makeDebugSettingsController(context: AccountContext?) -> ViewController?
|
||||
|
||||
|
@ -102,7 +102,17 @@ final class HashtagSearchControllerNode: ASDisplayNode {
|
||||
self.myController?.displayNode.isHidden = true
|
||||
self.globalController?.displayNode.isHidden = true
|
||||
|
||||
self.isSearching.set(self.currentController?.searching.get() ?? .single(false))
|
||||
let isSearching: Signal<Bool, NoError>
|
||||
if let currentController = self.currentController {
|
||||
isSearching = .single(true)
|
||||
|> then(
|
||||
currentController.searching.get()
|
||||
|> delay(0.5, queue: Queue.mainQueue())
|
||||
)
|
||||
} else {
|
||||
isSearching = .single(false)
|
||||
}
|
||||
self.isSearching.set(isSearching)
|
||||
} else {
|
||||
self.myController?.displayNode.isHidden = false
|
||||
self.globalController?.displayNode.isHidden = true
|
||||
|
@ -63,6 +63,8 @@ final class HashtagSearchNavigationContentNode: NavigationBarContentNode {
|
||||
|
||||
super.init()
|
||||
|
||||
self.searchBar.autocapitalization = .none
|
||||
|
||||
if hasCurrentChat {
|
||||
self.addSubnode(self.searchBar)
|
||||
}
|
||||
|
@ -949,6 +949,15 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
public var autocapitalization: UITextAutocapitalizationType {
|
||||
get {
|
||||
return self.textField.autocapitalizationType
|
||||
}
|
||||
set {
|
||||
self.textField.autocapitalizationType = newValue
|
||||
}
|
||||
}
|
||||
|
||||
private var validLayout: (CGSize, CGFloat, CGFloat)?
|
||||
|
||||
private let fieldStyle: SearchBarStyle
|
||||
@ -962,7 +971,7 @@ public class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
||||
self.forceSeparator = forceSeparator
|
||||
self.cancelText = cancelText
|
||||
self.icon = icon
|
||||
|
||||
|
||||
self.backgroundNode = NavigationBackgroundNode(color: theme.background)
|
||||
self.backgroundNode.isUserInteractionEnabled = false
|
||||
self.backgroundNode.isHidden = !displayBackground
|
||||
|
@ -545,7 +545,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-1281329567] = { return Api.MessageAction.parse_messageActionGroupCallScheduled($0) }
|
||||
dict[-1615153660] = { return Api.MessageAction.parse_messageActionHistoryClear($0) }
|
||||
dict[1345295095] = { return Api.MessageAction.parse_messageActionInviteToGroupCall($0) }
|
||||
dict[-1776926890] = { return Api.MessageAction.parse_messageActionPaymentSent($0) }
|
||||
dict[-1482950556] = { return Api.MessageAction.parse_messageActionPaymentSent($0) }
|
||||
dict[-1892568281] = { return Api.MessageAction.parse_messageActionPaymentSentMe($0) }
|
||||
dict[-2132731265] = { return Api.MessageAction.parse_messageActionPhoneCall($0) }
|
||||
dict[-1799538451] = { return Api.MessageAction.parse_messageActionPinMessage($0) }
|
||||
|
@ -604,7 +604,7 @@ public extension Api {
|
||||
case messageActionGroupCallScheduled(call: Api.InputGroupCall, scheduleDate: Int32)
|
||||
case messageActionHistoryClear
|
||||
case messageActionInviteToGroupCall(call: Api.InputGroupCall, users: [Int64])
|
||||
case messageActionPaymentSent(flags: Int32, currency: String, totalAmount: Int64, invoiceSlug: String?)
|
||||
case messageActionPaymentSent(flags: Int32, currency: String, totalAmount: Int64, invoiceSlug: String?, charge: Api.PaymentCharge?)
|
||||
case messageActionPaymentSentMe(flags: Int32, currency: String, totalAmount: Int64, payload: Buffer, info: Api.PaymentRequestedInfo?, shippingOptionId: String?, charge: Api.PaymentCharge)
|
||||
case messageActionPhoneCall(flags: Int32, callId: Int64, reason: Api.PhoneCallDiscardReason?, duration: Int32?)
|
||||
case messageActionPinMessage
|
||||
@ -816,14 +816,15 @@ public extension Api {
|
||||
serializeInt64(item, buffer: buffer, boxed: false)
|
||||
}
|
||||
break
|
||||
case .messageActionPaymentSent(let flags, let currency, let totalAmount, let invoiceSlug):
|
||||
case .messageActionPaymentSent(let flags, let currency, let totalAmount, let invoiceSlug, let charge):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1776926890)
|
||||
buffer.appendInt32(-1482950556)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(currency, buffer: buffer, boxed: false)
|
||||
serializeInt64(totalAmount, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(invoiceSlug!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 4) != 0 {charge!.serialize(buffer, true)}
|
||||
break
|
||||
case .messageActionPaymentSentMe(let flags, let currency, let totalAmount, let payload, let info, let shippingOptionId, let charge):
|
||||
if boxed {
|
||||
@ -1017,8 +1018,8 @@ public extension Api {
|
||||
return ("messageActionHistoryClear", [])
|
||||
case .messageActionInviteToGroupCall(let call, let users):
|
||||
return ("messageActionInviteToGroupCall", [("call", call as Any), ("users", users as Any)])
|
||||
case .messageActionPaymentSent(let flags, let currency, let totalAmount, let invoiceSlug):
|
||||
return ("messageActionPaymentSent", [("flags", flags as Any), ("currency", currency as Any), ("totalAmount", totalAmount as Any), ("invoiceSlug", invoiceSlug as Any)])
|
||||
case .messageActionPaymentSent(let flags, let currency, let totalAmount, let invoiceSlug, let charge):
|
||||
return ("messageActionPaymentSent", [("flags", flags as Any), ("currency", currency as Any), ("totalAmount", totalAmount as Any), ("invoiceSlug", invoiceSlug as Any), ("charge", charge as Any)])
|
||||
case .messageActionPaymentSentMe(let flags, let currency, let totalAmount, let payload, let info, let shippingOptionId, let charge):
|
||||
return ("messageActionPaymentSentMe", [("flags", flags as Any), ("currency", currency as Any), ("totalAmount", totalAmount as Any), ("payload", payload as Any), ("info", info as Any), ("shippingOptionId", shippingOptionId as Any), ("charge", charge as Any)])
|
||||
case .messageActionPhoneCall(let flags, let callId, let reason, let duration):
|
||||
@ -1395,12 +1396,17 @@ public extension Api {
|
||||
_3 = reader.readInt64()
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
|
||||
var _5: Api.PaymentCharge?
|
||||
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
|
||||
_5 = Api.parse(reader, signature: signature) as? Api.PaymentCharge
|
||||
} }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.MessageAction.messageActionPaymentSent(flags: _1!, currency: _2!, totalAmount: _3!, invoiceSlug: _4)
|
||||
let _c5 = (Int(_1!) & Int(1 << 4) == 0) || _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.MessageAction.messageActionPaymentSent(flags: _1!, currency: _2!, totalAmount: _3!, invoiceSlug: _4, charge: _5)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
@ -40,10 +40,18 @@ func telegramMediaActionFromApiAction(_ action: Api.MessageAction) -> TelegramMe
|
||||
return TelegramMediaAction(action: .phoneCall(callId: callId, discardReason: discardReason, duration: duration, isVideo: isVideo))
|
||||
case .messageActionEmpty:
|
||||
return nil
|
||||
case let .messageActionPaymentSent(flags, currency, totalAmount, invoiceSlug):
|
||||
case let .messageActionPaymentSent(flags, currency, totalAmount, invoiceSlug, charge):
|
||||
let isRecurringInit = (flags & (1 << 2)) != 0
|
||||
let isRecurringUsed = (flags & (1 << 3)) != 0
|
||||
return TelegramMediaAction(action: .paymentSent(currency: currency, totalAmount: totalAmount, invoiceSlug: invoiceSlug, isRecurringInit: isRecurringInit, isRecurringUsed: isRecurringUsed))
|
||||
|
||||
let chargeId: String?
|
||||
switch charge {
|
||||
case let .paymentCharge(id, _):
|
||||
chargeId = id
|
||||
default:
|
||||
chargeId = nil
|
||||
}
|
||||
return TelegramMediaAction(action: .paymentSent(currency: currency, totalAmount: totalAmount, invoiceSlug: invoiceSlug, isRecurringInit: isRecurringInit, isRecurringUsed: isRecurringUsed, chargeId: chargeId))
|
||||
case .messageActionPaymentSentMe:
|
||||
return nil
|
||||
case .messageActionScreenshotTaken:
|
||||
|
@ -101,7 +101,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
case messageAutoremoveTimeoutUpdated(period: Int32, autoSettingSource: PeerId?)
|
||||
case gameScore(gameId: Int64, score: Int32)
|
||||
case phoneCall(callId: Int64, discardReason: PhoneCallDiscardReason?, duration: Int32?, isVideo: Bool)
|
||||
case paymentSent(currency: String, totalAmount: Int64, invoiceSlug: String?, isRecurringInit: Bool, isRecurringUsed: Bool)
|
||||
case paymentSent(currency: String, totalAmount: Int64, invoiceSlug: String?, isRecurringInit: Bool, isRecurringUsed: Bool, chargeId: String?)
|
||||
case customText(text: String, entities: [MessageTextEntity], additionalAttributes: CustomTextAttributes?)
|
||||
case botDomainAccessGranted(domain: String)
|
||||
case botAppAccessGranted(appName: String?, type: BotSendMessageAccessGrantedType?)
|
||||
@ -164,7 +164,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
}
|
||||
self = .phoneCall(callId: decoder.decodeInt64ForKey("i", orElse: 0), discardReason: discardReason, duration: decoder.decodeInt32ForKey("d", orElse: 0), isVideo: decoder.decodeInt32ForKey("vc", orElse: 0) != 0)
|
||||
case 15:
|
||||
self = .paymentSent(currency: decoder.decodeStringForKey("currency", orElse: ""), totalAmount: decoder.decodeInt64ForKey("ta", orElse: 0), invoiceSlug: decoder.decodeOptionalStringForKey("invoiceSlug"), isRecurringInit: decoder.decodeBoolForKey("isRecurringInit", orElse: false), isRecurringUsed: decoder.decodeBoolForKey("isRecurringUsed", orElse: false))
|
||||
self = .paymentSent(currency: decoder.decodeStringForKey("currency", orElse: ""), totalAmount: decoder.decodeInt64ForKey("ta", orElse: 0), invoiceSlug: decoder.decodeOptionalStringForKey("invoiceSlug"), isRecurringInit: decoder.decodeBoolForKey("isRecurringInit", orElse: false), isRecurringUsed: decoder.decodeBoolForKey("isRecurringUsed", orElse: false), chargeId: decoder.decodeOptionalStringForKey("chargeId"))
|
||||
case 16:
|
||||
self = .customText(text: decoder.decodeStringForKey("text", orElse: ""), entities: decoder.decodeObjectArrayWithDecoderForKey("ent"), additionalAttributes: nil)
|
||||
case 17:
|
||||
@ -293,7 +293,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
encoder.encodeInt32(13, forKey: "_rawValue")
|
||||
encoder.encodeInt64(gameId, forKey: "i")
|
||||
encoder.encodeInt32(score, forKey: "s")
|
||||
case let .paymentSent(currency, totalAmount, invoiceSlug, isRecurringInit, isRecurringUsed):
|
||||
case let .paymentSent(currency, totalAmount, invoiceSlug, isRecurringInit, isRecurringUsed, chargeId):
|
||||
encoder.encodeInt32(15, forKey: "_rawValue")
|
||||
encoder.encodeString(currency, forKey: "currency")
|
||||
encoder.encodeInt64(totalAmount, forKey: "ta")
|
||||
@ -304,6 +304,11 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
||||
}
|
||||
encoder.encodeBool(isRecurringInit, forKey: "isRecurringInit")
|
||||
encoder.encodeBool(isRecurringUsed, forKey: "isRecurringUsed")
|
||||
if let chargeId = chargeId {
|
||||
encoder.encodeString(chargeId, forKey: "chargeId")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "chargeId")
|
||||
}
|
||||
case let .phoneCall(callId, discardReason, duration, isVideo):
|
||||
encoder.encodeInt32(14, forKey: "_rawValue")
|
||||
encoder.encodeInt64(callId, forKey: "i")
|
||||
|
@ -563,7 +563,7 @@ func _internal_sendBotPaymentForm(account: Account, formId: Int64, source: BotPa
|
||||
switch source {
|
||||
case let .slug(slug):
|
||||
for media in message.media {
|
||||
if let action = media as? TelegramMediaAction, case let .paymentSent(_, _, invoiceSlug?, _, _) = action.action, invoiceSlug == slug {
|
||||
if let action = media as? TelegramMediaAction, case let .paymentSent(_, _, invoiceSlug?, _, _, _) = action.action, invoiceSlug == slug {
|
||||
if case let .Id(id) = message.id {
|
||||
receiptMessageId = id
|
||||
}
|
||||
|
@ -366,7 +366,7 @@ func _internal_sendStarsPaymentForm(account: Account, formId: Int64, source: Bot
|
||||
switch source {
|
||||
case let .slug(slug):
|
||||
for media in message.media {
|
||||
if let action = media as? TelegramMediaAction, case let .paymentSent(_, _, invoiceSlug?, _, _) = action.action, invoiceSlug == slug {
|
||||
if let action = media as? TelegramMediaAction, case let .paymentSent(_, _, invoiceSlug?, _, _, _) = action.action, invoiceSlug == slug {
|
||||
if case let .Id(id) = message.id {
|
||||
receiptMessageId = id
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
||||
var argumentAttributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: [(0, message.author?.id)])
|
||||
argumentAttributes[1] = MarkdownAttributeSet(font: titleBoldFont, textColor: primaryTextColor, additionalAttributes: [:])
|
||||
attributedString = addAttributesToStringWithRanges(formatWithArgumentRanges(baseString, ranges, [authorName, gameTitle ?? ""]), body: bodyAttributes, argumentAttributes: argumentAttributes)
|
||||
case let .paymentSent(currency, totalAmount, _, isRecurringInit, isRecurringUsed):
|
||||
case let .paymentSent(currency, totalAmount, _, isRecurringInit, isRecurringUsed, _):
|
||||
var invoiceMessage: EngineMessage?
|
||||
for attribute in message.attributes {
|
||||
if let attribute = attribute as? ReplyMessageAttribute, let message = message.associatedMessages[attribute.messageId] {
|
||||
@ -548,13 +548,11 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
||||
range = (mutableString.string as NSString).range(of: "{amount}")
|
||||
if range.location != NSNotFound {
|
||||
if currency == "XTR" {
|
||||
let amountAttributedString = NSMutableAttributedString(string: " > \(totalAmount)", font: titleBoldFont, textColor: primaryTextColor)
|
||||
if let range = amountAttributedString.string.range(of: ">"), let starImage = generateScaledImage(image: UIImage(bundleImageName: "Premium/Stars/Star"), size: CGSize(width: 16.0, height: 16.0), opaque: false)?.withRenderingMode(.alwaysTemplate) {
|
||||
amountAttributedString.addAttribute(.attachment, value: starImage, range: NSRange(range, in: amountAttributedString.string))
|
||||
amountAttributedString.addAttribute(.foregroundColor, value: primaryTextColor, range: NSRange(range, in: amountAttributedString.string))
|
||||
let amountAttributedString = NSMutableAttributedString(string: "#\(totalAmount)", font: titleBoldFont, textColor: primaryTextColor)
|
||||
if let range = amountAttributedString.string.range(of: "#") {
|
||||
amountAttributedString.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars), range: NSRange(range, in: amountAttributedString.string))
|
||||
amountAttributedString.addAttribute(.baselineOffset, value: 1.5, range: NSRange(range, in: amountAttributedString.string))
|
||||
}
|
||||
|
||||
mutableString.replaceCharacters(in: range, with: amountAttributedString)
|
||||
} else {
|
||||
mutableString.replaceCharacters(in: range, with: NSAttributedString(string: formatCurrencyAmount(totalAmount, currency: currency), font: titleBoldFont, textColor: primaryTextColor))
|
||||
|
@ -98,6 +98,7 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
||||
var result: [(Message, AnyClass, ChatMessageEntryAttributes, BubbleItemAttributes)] = []
|
||||
var skipText = false
|
||||
var messageWithCaptionToAdd: (Message, ChatMessageEntryAttributes)?
|
||||
var messageWithFactCheckToAdd: (Message, ChatMessageEntryAttributes)?
|
||||
var isUnsupportedMedia = false
|
||||
var isStoryWithText = false
|
||||
var isAction = false
|
||||
@ -263,6 +264,10 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
||||
}
|
||||
}
|
||||
|
||||
if let attribute = message.factCheckAttribute, case .Loaded = attribute.content, messageWithFactCheckToAdd == nil {
|
||||
messageWithFactCheckToAdd = (message, itemAttributes)
|
||||
}
|
||||
|
||||
inner: for media in message.media {
|
||||
if let webpage = media as? TelegramMediaWebpage {
|
||||
if case let .Loaded(content) = webpage.content {
|
||||
@ -294,14 +299,6 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
||||
if isUnsupportedMedia {
|
||||
result.append((message, ChatMessageUnsupportedBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
needReactions = false
|
||||
} else {
|
||||
for attribute in message.attributes {
|
||||
if let attribute = attribute as? FactCheckMessageAttribute, case .Loaded = attribute.content {
|
||||
result.append((message, ChatMessageFactCheckBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
needReactions = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -317,6 +314,11 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> ([
|
||||
}
|
||||
}
|
||||
|
||||
if let (messageWithFactCheckToAdd, itemAttributes) = messageWithFactCheckToAdd, !hasSeparateCommentsButton {
|
||||
result.append((messageWithFactCheckToAdd, ChatMessageFactCheckBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .text, neighborSpacing: .default)))
|
||||
needReactions = false
|
||||
}
|
||||
|
||||
if let additionalContent = item.additionalContent {
|
||||
switch additionalContent {
|
||||
case let .eventLogPreviousMessage(previousMessage):
|
||||
|
@ -395,6 +395,9 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
||||
self.updateTopicInfo(topicInfo: (id, info))
|
||||
case let .nameColors(colors):
|
||||
self.updateNameColors(colors: colors)
|
||||
case .stars:
|
||||
self.updateStars()
|
||||
self.updateTintColor()
|
||||
}
|
||||
} else if let file = file {
|
||||
self.updateFile(file: file, attemptSynchronousLoad: attemptSynchronousLoad)
|
||||
@ -480,6 +483,8 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
||||
if file.isCustomTemplateEmoji {
|
||||
customColor = self.dynamicColor
|
||||
}
|
||||
} else if let emoji = self.arguments?.emoji, let custom = emoji.custom, case .stars = custom {
|
||||
customColor = self.dynamicColor
|
||||
}
|
||||
|
||||
if customColor != nil {
|
||||
@ -574,6 +579,10 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
||||
self.contents = image?.cgImage
|
||||
}
|
||||
|
||||
private func updateStars() {
|
||||
self.contents = starImage?.cgImage
|
||||
}
|
||||
|
||||
private func updateFile(file: TelegramMediaFile, attemptSynchronousLoad: Bool) {
|
||||
guard let arguments = self.arguments else {
|
||||
return
|
||||
@ -833,3 +842,13 @@ public final class CustomEmojiContainerView: UIView {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private let starImage: UIImage? = {
|
||||
generateImage(CGSize(width: 32.0, height: 32.0), contextGenerator: { size, context in
|
||||
context.clear(CGRect(origin: .zero, size: size))
|
||||
|
||||
if let image = generateTintedImage(image: UIImage(bundleImageName: "Premium/Stars/Star"), color: .white), let cgImage = image.cgImage {
|
||||
context.draw(cgImage, in: CGRect(origin: .zero, size: size).insetBy(dx: 2.0, dy: 2.0), byTiling: false)
|
||||
}
|
||||
})?.withRenderingMode(.alwaysTemplate)
|
||||
}()
|
||||
|
@ -79,6 +79,8 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
if case let .peer(peer) = transaction.peer {
|
||||
peerIds.append(peer.id)
|
||||
}
|
||||
case let .receipt(receipt, _, _):
|
||||
peerIds.append(receipt.botPaymentId)
|
||||
}
|
||||
|
||||
self.disposable = (context.engine.data.get(
|
||||
@ -159,18 +161,20 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
let additionalText: String
|
||||
let buttonText: String
|
||||
|
||||
let transactionId: String
|
||||
let count: Int64
|
||||
let transactionId: String?
|
||||
let date: Int32
|
||||
let toPeer: EnginePeer?
|
||||
let photo: TelegramMediaWebFile?
|
||||
|
||||
let gloss = false
|
||||
switch subject {
|
||||
case let .transaction(transaction):
|
||||
switch transaction.peer {
|
||||
case .peer:
|
||||
titleText = "Product Title"
|
||||
case let .peer(peer):
|
||||
titleText = transaction.title ?? peer.compactDisplayTitle
|
||||
case .appStore:
|
||||
titleText = "In-app Purchase"
|
||||
titleText = "In-App Purchase"
|
||||
case .playMarket:
|
||||
titleText = "Play Market"
|
||||
case .premiumBot:
|
||||
@ -181,14 +185,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
titleText = "Unsupported"
|
||||
}
|
||||
|
||||
if transaction.count < 0 {
|
||||
descriptionText = "- \(transaction.count * -1) ⭐️"
|
||||
} else {
|
||||
descriptionText = "+ \(transaction.count) ⭐️"
|
||||
}
|
||||
additionalText = strings.Stars_Transaction_Terms
|
||||
buttonText = strings.Common_OK
|
||||
|
||||
count = transaction.count
|
||||
transactionId = transaction.id
|
||||
date = transaction.date
|
||||
if case let .peer(peer) = transaction.peer {
|
||||
@ -196,6 +193,27 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
} else {
|
||||
toPeer = nil
|
||||
}
|
||||
photo = transaction.photo
|
||||
case let .receipt(receipt, id, dateValue):
|
||||
titleText = receipt.invoiceMedia.title
|
||||
count = (receipt.invoice.prices.first?.amount ?? receipt.invoiceMedia.totalAmount) * -1
|
||||
transactionId = id
|
||||
date = dateValue
|
||||
if let peer = state.peerMap[receipt.botPaymentId] {
|
||||
toPeer = peer
|
||||
} else {
|
||||
toPeer = nil
|
||||
}
|
||||
photo = receipt.invoiceMedia.photo
|
||||
}
|
||||
|
||||
additionalText = strings.Stars_Transaction_Terms
|
||||
buttonText = strings.Common_OK
|
||||
|
||||
if count < 0 {
|
||||
descriptionText = "- \(count * -1) ⭐️"
|
||||
} else {
|
||||
descriptionText = "+ \(count) ⭐️"
|
||||
}
|
||||
|
||||
let title = title.update(
|
||||
@ -218,6 +236,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
context: component.context,
|
||||
theme: theme,
|
||||
peers: toPeer.flatMap { [$0] } ?? [],
|
||||
photo: photo,
|
||||
isVisible: true,
|
||||
hasIdleAnimations: true,
|
||||
hasScaleAnimation: false,
|
||||
@ -247,7 +266,7 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
if let toPeer {
|
||||
tableItems.append(.init(
|
||||
id: "to",
|
||||
title: strings.Stars_Transaction_Date,
|
||||
title: strings.Stars_Transaction_To,
|
||||
component: AnyComponent(
|
||||
Button(
|
||||
content: AnyComponent(
|
||||
@ -270,21 +289,23 @@ private final class StarsTransactionSheetContent: CombinedComponent {
|
||||
))
|
||||
}
|
||||
|
||||
tableItems.append(.init(
|
||||
id: "transaction",
|
||||
title: strings.Stars_Transaction_Id,
|
||||
component: AnyComponent(
|
||||
TransactionCellComponent(
|
||||
textColor: tableTextColor,
|
||||
accentColor: tableLinkColor,
|
||||
transactionId: transactionId,
|
||||
copy: {
|
||||
component.copyTransactionId()
|
||||
}
|
||||
)
|
||||
),
|
||||
insets: UIEdgeInsets(top: 0.0, left: 12.0, bottom: 0.0, right: 5.0)
|
||||
))
|
||||
if let transactionId {
|
||||
tableItems.append(.init(
|
||||
id: "transaction",
|
||||
title: strings.Stars_Transaction_Id,
|
||||
component: AnyComponent(
|
||||
TransactionCellComponent(
|
||||
textColor: tableTextColor,
|
||||
accentColor: tableLinkColor,
|
||||
transactionId: transactionId,
|
||||
copy: {
|
||||
component.copyTransactionId()
|
||||
}
|
||||
)
|
||||
),
|
||||
insets: UIEdgeInsets(top: 0.0, left: 12.0, bottom: 0.0, right: 5.0)
|
||||
))
|
||||
}
|
||||
|
||||
tableItems.append(.init(
|
||||
id: "date",
|
||||
@ -522,6 +543,7 @@ private final class StarsTransactionSheetComponent: CombinedComponent {
|
||||
public class StarsTransactionScreen: ViewControllerComponentContainer {
|
||||
public enum Subject: Equatable {
|
||||
case transaction(StarsContext.State.Transaction)
|
||||
case receipt(receipt: BotPaymentReceipt, id: String?, date: Int32)
|
||||
}
|
||||
|
||||
private let context: AccountContext
|
||||
|
@ -1041,8 +1041,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if canSetupAutoremoveTimeout {
|
||||
strongSelf.presentAutoremoveSetup()
|
||||
}
|
||||
case .paymentSent:
|
||||
strongSelf.present(BotReceiptController(context: strongSelf.context, messageId: message.id), in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
case let .paymentSent(currency, _, _, _, _, id):
|
||||
if currency == "XTR" {
|
||||
let _ = (context.engine.payments.requestBotPaymentReceipt(messageId: message.id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] receipt in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.push(self.context.sharedContext.makeStarsReceiptScreen(context: self.context, receipt: receipt, id: id, date: message.timestamp))
|
||||
})
|
||||
} else {
|
||||
strongSelf.present(BotReceiptController(context: strongSelf.context, messageId: message.id), in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}
|
||||
/*for attribute in message.attributes {
|
||||
if let attribute = attribute as? ReplyMessageAttribute {
|
||||
//strongSelf.navigateToMessage(from: message.id, to: .id(attribute.messageId))
|
||||
@ -2709,19 +2719,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, color: .accent, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
if let strongSelf = self {
|
||||
let peerSignal: Signal<Peer?, NoError>
|
||||
guard let peerId = strongSelf.chatLocation.peerId else {
|
||||
return
|
||||
}
|
||||
peerSignal = strongSelf.context.account.postbox.loadedPeerWithId(peerId)
|
||||
|> map(Optional.init)
|
||||
let _ = (peerSignal
|
||||
|> deliverOnMainQueue).startStandalone(next: { peer in
|
||||
if let strongSelf = self {
|
||||
let searchController = HashtagSearchController(context: strongSelf.context, peer: peer.flatMap(EnginePeer.init), query: hashtag)
|
||||
strongSelf.effectiveNavigationController?.pushViewController(searchController)
|
||||
}
|
||||
})
|
||||
strongSelf.openHashtag(hashtag, peerName: nil)
|
||||
}
|
||||
}),
|
||||
ActionSheetButtonItem(title: strongSelf.presentationData.strings.Conversation_LinkDialogCopy, color: .accent, action: { [weak actionSheet] in
|
||||
@ -2925,7 +2923,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if let invoice = media as? TelegramMediaInvoice {
|
||||
strongSelf.chatDisplayNode.dismissInput()
|
||||
if let receiptMessageId = invoice.receiptMessageId {
|
||||
strongSelf.present(BotReceiptController(context: strongSelf.context, messageId: receiptMessageId), in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
if invoice.currency == "XTR" {
|
||||
let _ = (strongSelf.context.engine.payments.requestBotPaymentReceipt(messageId: message.id)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] receipt in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.push(strongSelf.context.sharedContext.makeStarsReceiptScreen(context: strongSelf.context, receipt: receipt, id: nil, date: 0))
|
||||
})
|
||||
} else {
|
||||
strongSelf.present(BotReceiptController(context: strongSelf.context, messageId: receiptMessageId), in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}
|
||||
} else {
|
||||
let inputData = Promise<BotCheckoutController.InputData?>()
|
||||
inputData.set(BotCheckoutController.InputData.fetch(context: strongSelf.context, source: .message(message.id))
|
||||
@ -9586,6 +9594,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.resolvePeerByNameDisposable?.set((resolveSignal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
if let strongSelf = self, !hashtag.isEmpty {
|
||||
// var peer = peer
|
||||
// if peer?.id.isReplies == true {
|
||||
// peer = nil
|
||||
// }
|
||||
let searchController = HashtagSearchController(context: strongSelf.context, peer: peer.flatMap(EnginePeer.init), query: hashtag)
|
||||
strongSelf.effectiveNavigationController?.pushViewController(searchController)
|
||||
}
|
||||
|
@ -2816,7 +2816,11 @@ class ChatControllerNode: ASDisplayNode, ASScrollViewDelegate {
|
||||
}
|
||||
self.skippedShowSearchResultsAsListAnimationOnce = true
|
||||
inlineSearchResultsView.layer.allowsGroupOpacity = true
|
||||
self.contentContainerNode.view.insertSubview(inlineSearchResultsView, aboveSubview: self.historyNodeContainer.view)
|
||||
if let inlineSearchResultsView = self.inlineSearchResults?.view {
|
||||
self.contentContainerNode.view.insertSubview(inlineSearchResultsView, aboveSubview: inlineSearchResultsView)
|
||||
} else {
|
||||
self.contentContainerNode.view.insertSubview(inlineSearchResultsView, aboveSubview: self.historyNodeContainer.view)
|
||||
}
|
||||
}
|
||||
inlineSearchResultsTransition.setFrame(view: inlineSearchResultsView, frame: CGRect(origin: CGPoint(), size: layout.size))
|
||||
|
||||
|
@ -480,6 +480,10 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
isEmbeddedMode = true
|
||||
}
|
||||
|
||||
if case let .customChatContents(customChatContents) = chatPresentationInterfaceState.subject, case .hashTagSearch = customChatContents.kind {
|
||||
isEmbeddedMode = true
|
||||
}
|
||||
|
||||
var hasExpandedAudioTranscription = false
|
||||
if let messageNode = messageNode as? ChatMessageBubbleItemNode {
|
||||
hasExpandedAudioTranscription = messageNode.hasExpandedAudioTranscription()
|
||||
@ -1703,29 +1707,28 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
clearCacheAsDelete = true
|
||||
}
|
||||
|
||||
|
||||
if let channel = message.peers[message.id.peerId] as? TelegramChannel, case .broadcast = channel.info, canEditFactCheck(appConfig: appConfig) {
|
||||
var hasFactCheck = false
|
||||
for attribute in message.attributes {
|
||||
if let _ = attribute as? FactCheckMessageAttribute {
|
||||
hasFactCheck = true
|
||||
break
|
||||
}
|
||||
var canAddFactCheck = true
|
||||
if message.media.contains(where: { $0 is TelegramMediaAction || $0 is TelegramMediaGiveaway }) {
|
||||
canAddFactCheck = false
|
||||
}
|
||||
|
||||
let title: String
|
||||
if hasFactCheck {
|
||||
title = chatPresentationInterfaceState.strings.Conversation_ContextMenuEditFactCheck
|
||||
} else {
|
||||
title = chatPresentationInterfaceState.strings.Conversation_ContextMenuAddFactCheck
|
||||
if canAddFactCheck {
|
||||
let hasFactCheck = message.factCheckAttribute != nil
|
||||
let title: String
|
||||
if hasFactCheck {
|
||||
title = chatPresentationInterfaceState.strings.Conversation_ContextMenuEditFactCheck
|
||||
} else {
|
||||
title = chatPresentationInterfaceState.strings.Conversation_ContextMenuAddFactCheck
|
||||
}
|
||||
actions.append(.action(ContextMenuActionItem(text: title, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/FactCheck"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { c, f in
|
||||
c?.dismiss(completion: {
|
||||
controllerInteraction.editMessageFactCheck(messages[0].id)
|
||||
})
|
||||
})))
|
||||
}
|
||||
actions.append(.action(ContextMenuActionItem(text: title, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/FactCheck"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { c, f in
|
||||
c?.dismiss(completion: {
|
||||
controllerInteraction.editMessageFactCheck(messages[0].id)
|
||||
})
|
||||
})))
|
||||
}
|
||||
// if message.id.peerId.isGroupOrChannel {
|
||||
// //TODO:localize
|
||||
@ -1985,12 +1988,11 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
}
|
||||
|
||||
if let message = messages.first, case let .customChatContents(customChatContents) = chatPresentationInterfaceState.subject {
|
||||
actions.removeAll()
|
||||
|
||||
switch customChatContents.kind {
|
||||
case .hashTagSearch:
|
||||
break
|
||||
case .quickReplyMessageInput:
|
||||
actions.removeAll()
|
||||
if !messageText.isEmpty || (resourceAvailable && isImage) || diceEmoji != nil {
|
||||
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuCopy, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.actionSheet.primaryTextColor)
|
||||
@ -2054,7 +2056,7 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
})))
|
||||
}
|
||||
case .businessLinkSetup:
|
||||
break
|
||||
actions.removeAll()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2634,6 +2634,10 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
public func makeStarsTransactionScreen(context: AccountContext, transaction: StarsContext.State.Transaction) -> ViewController {
|
||||
return StarsTransactionScreen(context: context, subject: .transaction(transaction), action: {})
|
||||
}
|
||||
|
||||
public func makeStarsReceiptScreen(context: AccountContext, receipt: BotPaymentReceipt, id: String?, date: Int32) -> ViewController {
|
||||
return StarsTransactionScreen(context: context, subject: .receipt(receipt: receipt, id: id, date: date), action: {})
|
||||
}
|
||||
}
|
||||
|
||||
private func peerInfoControllerImpl(context: AccountContext, updatedPresentationData: (PresentationData, Signal<PresentationData, NoError>)?, peer: Peer, mode: PeerInfoControllerMode, avatarInitiallyExpanded: Bool, isOpenedFromChat: Bool, requestsContext: PeerInvitationImportersContext? = nil) -> ViewController? {
|
||||
|
@ -286,6 +286,7 @@ public final class ChatTextInputTextCustomEmojiAttribute: NSObject, Codable {
|
||||
public enum Custom: Codable {
|
||||
case topic(id: Int64, info: EngineMessageHistoryThread.Info)
|
||||
case nameColors([UInt32])
|
||||
case stars
|
||||
}
|
||||
|
||||
public let interactivelySelectedFromPackId: ItemCollectionId?
|
||||
|
Loading…
x
Reference in New Issue
Block a user