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