Various improvements

This commit is contained in:
Ilya Laktyushin 2024-05-24 13:56:24 +04:00
parent d7f7eefd4b
commit 3ef498d39a
19 changed files with 203 additions and 98 deletions

View File

@ -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?

View File

@ -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

View File

@ -63,6 +63,8 @@ final class HashtagSearchNavigationContentNode: NavigationBarContentNode {
super.init()
self.searchBar.autocapitalization = .none
if hasCurrentChat {
self.addSubnode(self.searchBar)
}

View File

@ -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

View File

@ -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) }

View File

@ -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

View File

@ -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:

View File

@ -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")

View File

@ -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
}

View File

@ -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
}

View File

@ -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))

View File

@ -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):

View File

@ -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)
}()

View File

@ -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

View File

@ -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)
}

View File

@ -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))

View File

@ -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()
}
}

View File

@ -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? {

View File

@ -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?