mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-28 19:05:49 +00:00
Various improvements
This commit is contained in:
parent
29ee666889
commit
62b50d9e49
@ -1713,7 +1713,7 @@ open class TextNode: ASDisplayNode {
|
||||
embeddedItems.append(TextNodeEmbeddedItem(range: NSMakeRange(startIndex, endIndex - startIndex + 1), frame: CGRect(x: min(leftOffset, rightOffset), y: descent - (ascent + descent), width: abs(rightOffset - leftOffset) + rightInset, height: ascent + descent), item: item))
|
||||
}
|
||||
|
||||
func addAttachment(attachment: UIImage, line: CTLine, ascent: CGFloat, descent: CGFloat, startIndex: Int, endIndex: Int, rightInset: CGFloat = 0.0) {
|
||||
func addAttachment(attachment: UIImage, line: CTLine, ascent: CGFloat, descent: CGFloat, startIndex: Int, endIndex: Int, isAtEndOfTheLine: Bool, rightInset: CGFloat = 0.0) {
|
||||
var secondaryLeftOffset: CGFloat = 0.0
|
||||
let rawLeftOffset = CTLineGetOffsetForStringIndex(line, startIndex, &secondaryLeftOffset)
|
||||
var leftOffset = floor(rawLeftOffset)
|
||||
@ -1721,11 +1721,17 @@ open class TextNode: ASDisplayNode {
|
||||
leftOffset = floor(secondaryLeftOffset)
|
||||
}
|
||||
|
||||
var secondaryRightOffset: CGFloat = 0.0
|
||||
let rawRightOffset = CTLineGetOffsetForStringIndex(line, endIndex, &secondaryRightOffset)
|
||||
var rightOffset = ceil(rawRightOffset)
|
||||
if !rawRightOffset.isEqual(to: secondaryRightOffset) {
|
||||
rightOffset = ceil(secondaryRightOffset)
|
||||
var rightOffset: CGFloat = leftOffset
|
||||
if isAtEndOfTheLine {
|
||||
let rawRightOffset = CTLineGetTypographicBounds(line, nil, nil, nil)
|
||||
rightOffset = floor(rawRightOffset)
|
||||
} else {
|
||||
var secondaryRightOffset: CGFloat = 0.0
|
||||
let rawRightOffset = CTLineGetOffsetForStringIndex(line, endIndex, &secondaryRightOffset)
|
||||
rightOffset = ceil(rawRightOffset)
|
||||
if !rawRightOffset.isEqual(to: secondaryRightOffset) {
|
||||
rightOffset = ceil(secondaryRightOffset)
|
||||
}
|
||||
}
|
||||
|
||||
attachments.append(TextNodeAttachment(range: NSMakeRange(startIndex, endIndex - startIndex), frame: CGRect(x: min(leftOffset, rightOffset), y: descent - (ascent + descent), width: abs(rightOffset - leftOffset) + rightInset, height: ascent + descent), attachment: attachment))
|
||||
@ -1918,7 +1924,7 @@ open class TextNode: ASDisplayNode {
|
||||
var descent: CGFloat = 0.0
|
||||
CTLineGetTypographicBounds(coreTextLine, &ascent, &descent, nil)
|
||||
|
||||
addAttachment(attachment: attachment, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: range.location + range.length)
|
||||
addAttachment(attachment: attachment, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: max(range.location, min(lineRange.location + lineRange.length - 1, range.location + range.length)), isAtEndOfTheLine: range.location + range.length >= lineRange.location + lineRange.length - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2037,7 +2043,7 @@ open class TextNode: ASDisplayNode {
|
||||
var descent: CGFloat = 0.0
|
||||
CTLineGetTypographicBounds(coreTextLine, &ascent, &descent, nil)
|
||||
|
||||
addAttachment(attachment: attachment, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: range.location + range.length)
|
||||
addAttachment(attachment: attachment, line: coreTextLine, ascent: ascent, descent: descent, startIndex: range.location, endIndex: max(range.location, min(lineRange.location + lineRange.length - 1, range.location + range.length)), isAtEndOfTheLine: range.location + range.length >= lineRange.location + lineRange.length - 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,81 +15,108 @@ public enum ChatContextResultMessage: PostboxCoding, Equatable, Codable {
|
||||
}
|
||||
|
||||
case auto(caption: String, entities: TextEntitiesMessageAttribute?, replyMarkup: ReplyMarkupMessageAttribute?)
|
||||
case text(text: String, entities: TextEntitiesMessageAttribute?, disableUrlPreview: Bool, replyMarkup: ReplyMarkupMessageAttribute?)
|
||||
case text(text: String, entities: TextEntitiesMessageAttribute?, disableUrlPreview: Bool, previewParameters: WebpagePreviewMessageAttribute?, replyMarkup: ReplyMarkupMessageAttribute?)
|
||||
case mapLocation(media: TelegramMediaMap, replyMarkup: ReplyMarkupMessageAttribute?)
|
||||
case contact(media: TelegramMediaContact, replyMarkup: ReplyMarkupMessageAttribute?)
|
||||
case invoice(media: TelegramMediaInvoice, replyMarkup: ReplyMarkupMessageAttribute?)
|
||||
case webpage(text: String, entities: TextEntitiesMessageAttribute?, url: String, previewParameters: WebpagePreviewMessageAttribute?, replyMarkup: ReplyMarkupMessageAttribute?)
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
switch decoder.decodeInt32ForKey("_v", orElse: 0) {
|
||||
case 0:
|
||||
self = .auto(caption: decoder.decodeStringForKey("c", orElse: ""), entities: decoder.decodeObjectForKey("e") as? TextEntitiesMessageAttribute, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
case 1:
|
||||
self = .text(text: decoder.decodeStringForKey("t", orElse: ""), entities: decoder.decodeObjectForKey("e") as? TextEntitiesMessageAttribute, disableUrlPreview: decoder.decodeInt32ForKey("du", orElse: 0) != 0, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
case 2:
|
||||
self = .mapLocation(media: decoder.decodeObjectForKey("l") as! TelegramMediaMap, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
case 3:
|
||||
self = .contact(media: decoder.decodeObjectForKey("c") as! TelegramMediaContact, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
case 4:
|
||||
self = .invoice(media: decoder.decodeObjectForKey("i") as! TelegramMediaInvoice, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
default:
|
||||
self = .auto(caption: "", entities: nil, replyMarkup: nil)
|
||||
case 0:
|
||||
self = .auto(caption: decoder.decodeStringForKey("c", orElse: ""), entities: decoder.decodeObjectForKey("e") as? TextEntitiesMessageAttribute, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
case 1:
|
||||
self = .text(text: decoder.decodeStringForKey("t", orElse: ""), entities: decoder.decodeObjectForKey("e") as? TextEntitiesMessageAttribute, disableUrlPreview: decoder.decodeInt32ForKey("du", orElse: 0) != 0, previewParameters: decoder.decodeObjectForKey("prp") as? WebpagePreviewMessageAttribute, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
case 2:
|
||||
self = .mapLocation(media: decoder.decodeObjectForKey("l") as! TelegramMediaMap, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
case 3:
|
||||
self = .contact(media: decoder.decodeObjectForKey("c") as! TelegramMediaContact, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
case 4:
|
||||
self = .invoice(media: decoder.decodeObjectForKey("i") as! TelegramMediaInvoice, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
case 5:
|
||||
self = .webpage(text: decoder.decodeStringForKey("t", orElse: ""), entities: decoder.decodeObjectForKey("e") as? TextEntitiesMessageAttribute, url: decoder.decodeStringForKey("url", orElse: ""), previewParameters: decoder.decodeObjectForKey("prp") as? WebpagePreviewMessageAttribute, replyMarkup: decoder.decodeObjectForKey("m") as? ReplyMarkupMessageAttribute)
|
||||
default:
|
||||
self = .auto(caption: "", entities: nil, replyMarkup: nil)
|
||||
}
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
switch self {
|
||||
case let .auto(caption, entities, replyMarkup):
|
||||
encoder.encodeInt32(0, forKey: "_v")
|
||||
encoder.encodeString(caption, forKey: "c")
|
||||
if let entities = entities {
|
||||
encoder.encodeObject(entities, forKey: "e")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "e")
|
||||
}
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .text(text, entities, disableUrlPreview, replyMarkup):
|
||||
encoder.encodeInt32(1, forKey: "_v")
|
||||
encoder.encodeString(text, forKey: "t")
|
||||
if let entities = entities {
|
||||
encoder.encodeObject(entities, forKey: "e")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "e")
|
||||
}
|
||||
encoder.encodeInt32(disableUrlPreview ? 1 : 0, forKey: "du")
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .mapLocation(media, replyMarkup):
|
||||
encoder.encodeInt32(2, forKey: "_v")
|
||||
encoder.encodeObject(media, forKey: "l")
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .contact(media, replyMarkup):
|
||||
encoder.encodeInt32(3, forKey: "_v")
|
||||
encoder.encodeObject(media, forKey: "c")
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .invoice(media: media, replyMarkup):
|
||||
encoder.encodeInt32(4, forKey: "_v")
|
||||
encoder.encodeObject(media, forKey: "i")
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .auto(caption, entities, replyMarkup):
|
||||
encoder.encodeInt32(0, forKey: "_v")
|
||||
encoder.encodeString(caption, forKey: "c")
|
||||
if let entities = entities {
|
||||
encoder.encodeObject(entities, forKey: "e")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "e")
|
||||
}
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .text(text, entities, disableUrlPreview, previewParameters, replyMarkup):
|
||||
encoder.encodeInt32(1, forKey: "_v")
|
||||
encoder.encodeString(text, forKey: "t")
|
||||
if let entities = entities {
|
||||
encoder.encodeObject(entities, forKey: "e")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "e")
|
||||
}
|
||||
encoder.encodeInt32(disableUrlPreview ? 1 : 0, forKey: "du")
|
||||
if let previewParameters = previewParameters {
|
||||
encoder.encodeObject(previewParameters, forKey: "prp")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "prp")
|
||||
}
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .mapLocation(media, replyMarkup):
|
||||
encoder.encodeInt32(2, forKey: "_v")
|
||||
encoder.encodeObject(media, forKey: "l")
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .contact(media, replyMarkup):
|
||||
encoder.encodeInt32(3, forKey: "_v")
|
||||
encoder.encodeObject(media, forKey: "c")
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .invoice(media, replyMarkup):
|
||||
encoder.encodeInt32(4, forKey: "_v")
|
||||
encoder.encodeObject(media, forKey: "i")
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
case let .webpage(text, entities, url, previewParameters, replyMarkup):
|
||||
encoder.encodeInt32(5, forKey: "_v")
|
||||
encoder.encodeString(text, forKey: "t")
|
||||
if let entities = entities {
|
||||
encoder.encodeObject(entities, forKey: "e")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "e")
|
||||
}
|
||||
encoder.encodeString(url, forKey: "url")
|
||||
if let previewParameters = previewParameters {
|
||||
encoder.encodeObject(previewParameters, forKey: "prp")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "prp")
|
||||
}
|
||||
if let replyMarkup = replyMarkup {
|
||||
encoder.encodeObject(replyMarkup, forKey: "m")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "m")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,75 +137,99 @@ public enum ChatContextResultMessage: PostboxCoding, Equatable, Codable {
|
||||
|
||||
public static func ==(lhs: ChatContextResultMessage, rhs: ChatContextResultMessage) -> Bool {
|
||||
switch lhs {
|
||||
case let .auto(lhsCaption, lhsEntities, lhsReplyMarkup):
|
||||
if case let .auto(rhsCaption, rhsEntities, rhsReplyMarkup) = rhs {
|
||||
if lhsCaption != rhsCaption {
|
||||
return false
|
||||
}
|
||||
if lhsEntities != rhsEntities {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
case let .auto(lhsCaption, lhsEntities, lhsReplyMarkup):
|
||||
if case let .auto(rhsCaption, rhsEntities, rhsReplyMarkup) = rhs {
|
||||
if lhsCaption != rhsCaption {
|
||||
return false
|
||||
}
|
||||
case let .text(lhsText, lhsEntities, lhsDisableUrlPreview, lhsReplyMarkup):
|
||||
if case let .text(rhsText, rhsEntities, rhsDisableUrlPreview, rhsReplyMarkup) = rhs {
|
||||
if lhsText != rhsText {
|
||||
return false
|
||||
}
|
||||
if lhsEntities != rhsEntities {
|
||||
return false
|
||||
}
|
||||
if lhsDisableUrlPreview != rhsDisableUrlPreview {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
if lhsEntities != rhsEntities {
|
||||
return false
|
||||
}
|
||||
case let .mapLocation(lhsMedia, lhsReplyMarkup):
|
||||
if case let .mapLocation(rhsMedia, rhsReplyMarkup) = rhs {
|
||||
if !lhsMedia.isEqual(to: rhsMedia) {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
case let .contact(lhsMedia, lhsReplyMarkup):
|
||||
if case let .contact(rhsMedia, rhsReplyMarkup) = rhs {
|
||||
if !lhsMedia.isEqual(to: rhsMedia) {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .text(lhsText, lhsEntities, lhsDisableUrlPreview, lhsPreviewParameters, lhsReplyMarkup):
|
||||
if case let .text(rhsText, rhsEntities, rhsDisableUrlPreview, rhsPreviewParameters, rhsReplyMarkup) = rhs {
|
||||
if lhsText != rhsText {
|
||||
return false
|
||||
}
|
||||
case let .invoice(lhsMedia, lhsReplyMarkup):
|
||||
if case let .invoice(rhsMedia, rhsReplyMarkup) = rhs {
|
||||
if !lhsMedia.isEqual(to: rhsMedia) {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
if lhsEntities != rhsEntities {
|
||||
return false
|
||||
}
|
||||
if lhsDisableUrlPreview != rhsDisableUrlPreview {
|
||||
return false
|
||||
}
|
||||
if lhsPreviewParameters != rhsPreviewParameters {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .mapLocation(lhsMedia, lhsReplyMarkup):
|
||||
if case let .mapLocation(rhsMedia, rhsReplyMarkup) = rhs {
|
||||
if !lhsMedia.isEqual(to: rhsMedia) {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .contact(lhsMedia, lhsReplyMarkup):
|
||||
if case let .contact(rhsMedia, rhsReplyMarkup) = rhs {
|
||||
if !lhsMedia.isEqual(to: rhsMedia) {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .invoice(lhsMedia, lhsReplyMarkup):
|
||||
if case let .invoice(rhsMedia, rhsReplyMarkup) = rhs {
|
||||
if !lhsMedia.isEqual(to: rhsMedia) {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .webpage(lhsText, lhsEntities, lhsUrl, lhsPreviewParameters, lhsReplyMarkup):
|
||||
if case let .webpage(rhsText, rhsEntities, rhsUrl, rhsPreviewParameters, rhsReplyMarkup) = rhs {
|
||||
if lhsText != rhsText {
|
||||
return false
|
||||
}
|
||||
if lhsEntities != rhsEntities {
|
||||
return false
|
||||
}
|
||||
if lhsUrl != rhsUrl {
|
||||
return false
|
||||
}
|
||||
if lhsPreviewParameters != rhsPreviewParameters {
|
||||
return false
|
||||
}
|
||||
if lhsReplyMarkup != rhsReplyMarkup {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -458,7 +509,13 @@ extension ChatContextResultMessage {
|
||||
if let replyMarkup = replyMarkup {
|
||||
parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup)
|
||||
}
|
||||
self = .text(text: message, entities: parsedEntities, disableUrlPreview: (flags & (1 << 0)) != 0, replyMarkup: parsedReplyMarkup)
|
||||
let leadingPreview = (flags & (1 << 3)) != 0
|
||||
self = .text(text: message, entities: parsedEntities, disableUrlPreview: (flags & (1 << 0)) != 0, previewParameters: WebpagePreviewMessageAttribute(
|
||||
leadingPreview: leadingPreview,
|
||||
forceLargeMedia: nil,
|
||||
isManuallyAdded: false,
|
||||
isSafe: false
|
||||
), replyMarkup: parsedReplyMarkup)
|
||||
case let .botInlineMessageMediaGeo(_, geo, heading, period, proximityNotificationRadius, replyMarkup):
|
||||
let media = telegramMediaMapFromApiGeoPoint(geo, title: nil, address: nil, provider: nil, venueId: nil, venueType: nil, liveBroadcastingTimeout: period, liveProximityNotificationRadius: proximityNotificationRadius, heading: heading)
|
||||
var parsedReplyMarkup: ReplyMarkupMessageAttribute?
|
||||
@ -494,12 +551,38 @@ extension ChatContextResultMessage {
|
||||
}
|
||||
self = .invoice(media: TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: currency, totalAmount: totalAmount, startParam: "", extendedMedia: nil, flags: parsedFlags, version: TelegramMediaInvoice.lastVersion), replyMarkup: parsedReplyMarkup)
|
||||
case let .botInlineMessageMediaWebPage(flags, message, entities, url, replyMarkup):
|
||||
let _ = flags
|
||||
let _ = message
|
||||
let _ = entities
|
||||
let _ = url
|
||||
let _ = replyMarkup
|
||||
fatalError()
|
||||
var parsedReplyMarkup: ReplyMarkupMessageAttribute?
|
||||
if let replyMarkup = replyMarkup {
|
||||
parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup)
|
||||
}
|
||||
|
||||
let leadingPreview = (flags & (1 << 3)) != 0
|
||||
var forceLargeMedia: Bool?
|
||||
if (flags & (1 << 4)) != 0 {
|
||||
forceLargeMedia = true
|
||||
} else if (flags & (1 << 5)) != 0 {
|
||||
forceLargeMedia = false
|
||||
}
|
||||
let isManuallyAdded = (flags & (1 << 7)) != 0
|
||||
let isSafe = (flags & (1 << 8)) != 0
|
||||
|
||||
var parsedEntities: TextEntitiesMessageAttribute?
|
||||
if let entities = entities, !entities.isEmpty {
|
||||
parsedEntities = TextEntitiesMessageAttribute(entities: messageTextEntitiesFromApiEntities(entities))
|
||||
}
|
||||
|
||||
self = .webpage(
|
||||
text: message,
|
||||
entities: parsedEntities,
|
||||
url: url,
|
||||
previewParameters: WebpagePreviewMessageAttribute(
|
||||
leadingPreview: leadingPreview,
|
||||
forceLargeMedia: forceLargeMedia,
|
||||
isManuallyAdded: isManuallyAdded,
|
||||
isSafe: isSafe
|
||||
),
|
||||
replyMarkup: parsedReplyMarkup
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,137 +28,154 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, threadId:
|
||||
attributes.append(NotificationInfoMessageAttribute(flags: .muted))
|
||||
}
|
||||
switch result.message {
|
||||
case let .auto(caption, entities, replyMarkup):
|
||||
if let entities = entities {
|
||||
attributes.append(entities)
|
||||
}
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
switch result {
|
||||
case let .internalReference(internalReference):
|
||||
if internalReference.type == "game" {
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
let filteredAttributes = attributes.filter { attribute in
|
||||
if let _ = attribute as? ReplyMarkupMessageAttribute {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
if let media: Media = internalReference.file ?? internalReference.image {
|
||||
return .message(text: caption, attributes: filteredAttributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else {
|
||||
return .message(text: caption, attributes: filteredAttributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
}
|
||||
} else {
|
||||
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaGame(gameId: 0, accessHash: 0, name: "", title: internalReference.title ?? "", description: internalReference.description ?? "", image: internalReference.image, file: internalReference.file)), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
case let .auto(caption, entities, replyMarkup):
|
||||
if let entities = entities {
|
||||
attributes.append(entities)
|
||||
}
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
switch result {
|
||||
case let .internalReference(internalReference):
|
||||
if internalReference.type == "game" {
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat {
|
||||
let filteredAttributes = attributes.filter { attribute in
|
||||
if let _ = attribute as? ReplyMarkupMessageAttribute {
|
||||
return false
|
||||
}
|
||||
} else if let file = internalReference.file, internalReference.type == "gif" {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else if let image = internalReference.image {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: image), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else if let file = internalReference.file {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else {
|
||||
return nil
|
||||
return true
|
||||
}
|
||||
case let .externalReference(externalReference):
|
||||
if externalReference.type == "photo" {
|
||||
if let thumbnail = externalReference.thumbnail {
|
||||
var randomId: Int64 = 0
|
||||
arc4random_buf(&randomId, 8)
|
||||
let thumbnailResource = thumbnail.resource
|
||||
let imageDimensions = thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128)
|
||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: imageDimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: tmpImage), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
}
|
||||
} else if externalReference.type == "document" || externalReference.type == "gif" || externalReference.type == "audio" || externalReference.type == "voice" {
|
||||
var videoThumbnails: [TelegramMediaFile.VideoThumbnail] = []
|
||||
var previewRepresentations: [TelegramMediaImageRepresentation] = []
|
||||
if let thumbnail = externalReference.thumbnail {
|
||||
var randomId: Int64 = 0
|
||||
arc4random_buf(&randomId, 8)
|
||||
let thumbnailResource = thumbnail.resource
|
||||
|
||||
if thumbnail.mimeType.hasPrefix("video/") {
|
||||
videoThumbnails.append(TelegramMediaFile.VideoThumbnail(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource))
|
||||
} else {
|
||||
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
|
||||
}
|
||||
}
|
||||
var fileName = "file"
|
||||
if let content = externalReference.content {
|
||||
var contentUrl: String?
|
||||
if let resource = content.resource as? HttpReferenceMediaResource {
|
||||
contentUrl = resource.url
|
||||
} else if let resource = content.resource as? WebFileReferenceMediaResource {
|
||||
contentUrl = resource.url
|
||||
}
|
||||
if let contentUrl = contentUrl, let url = URL(string: contentUrl) {
|
||||
if !url.lastPathComponent.isEmpty {
|
||||
fileName = url.lastPathComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var fileAttributes: [TelegramMediaFileAttribute] = []
|
||||
fileAttributes.append(.FileName(fileName: fileName))
|
||||
|
||||
if externalReference.type == "gif" {
|
||||
fileAttributes.append(.Animated)
|
||||
}
|
||||
|
||||
if let dimensions = externalReference.content?.dimensions {
|
||||
fileAttributes.append(.ImageSize(size: dimensions))
|
||||
if externalReference.type == "gif" {
|
||||
fileAttributes.append(.Video(duration: externalReference.content?.duration ?? 0.0, size: dimensions, flags: [], preloadSize: nil))
|
||||
}
|
||||
}
|
||||
|
||||
if externalReference.type == "audio" || externalReference.type == "voice" {
|
||||
fileAttributes.append(.Audio(isVoice: externalReference.type == "voice", duration: Int(Int32(externalReference.content?.duration ?? 0)), title: externalReference.title, performer: externalReference.description, waveform: nil))
|
||||
}
|
||||
|
||||
var randomId: Int64 = 0
|
||||
arc4random_buf(&randomId, 8)
|
||||
|
||||
let resource: TelegramMediaResource
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat, let webResource = externalReference.content?.resource as? WebFileReferenceMediaResource {
|
||||
resource = webResource
|
||||
} else {
|
||||
resource = EmptyMediaResource()
|
||||
}
|
||||
|
||||
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, videoThumbnails: videoThumbnails, immediateThumbnailData: nil, mimeType: externalReference.content?.mimeType ?? "application/binary", size: nil, attributes: fileAttributes)
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
if let media: Media = internalReference.file ?? internalReference.image {
|
||||
return .message(text: caption, attributes: filteredAttributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
return .message(text: caption, attributes: filteredAttributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
}
|
||||
} else {
|
||||
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: TelegramMediaGame(gameId: 0, accessHash: 0, name: "", title: internalReference.title ?? "", description: internalReference.description ?? "", image: internalReference.image, file: internalReference.file)), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
}
|
||||
} else if let file = internalReference.file, internalReference.type == "gif" {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else if let image = internalReference.image {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: image), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else if let file = internalReference.file {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
case let .text(text, entities, _, replyMarkup):
|
||||
if let entities = entities {
|
||||
attributes.append(entities)
|
||||
case let .externalReference(externalReference):
|
||||
if externalReference.type == "photo" {
|
||||
if let thumbnail = externalReference.thumbnail {
|
||||
var randomId: Int64 = 0
|
||||
arc4random_buf(&randomId, 8)
|
||||
let thumbnailResource = thumbnail.resource
|
||||
let imageDimensions = thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128)
|
||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: imageDimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: tmpImage), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
}
|
||||
} else if externalReference.type == "document" || externalReference.type == "gif" || externalReference.type == "audio" || externalReference.type == "voice" {
|
||||
var videoThumbnails: [TelegramMediaFile.VideoThumbnail] = []
|
||||
var previewRepresentations: [TelegramMediaImageRepresentation] = []
|
||||
if let thumbnail = externalReference.thumbnail {
|
||||
var randomId: Int64 = 0
|
||||
arc4random_buf(&randomId, 8)
|
||||
let thumbnailResource = thumbnail.resource
|
||||
|
||||
if thumbnail.mimeType.hasPrefix("video/") {
|
||||
videoThumbnails.append(TelegramMediaFile.VideoThumbnail(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource))
|
||||
} else {
|
||||
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false, isPersonal: false))
|
||||
}
|
||||
}
|
||||
var fileName = "file"
|
||||
if let content = externalReference.content {
|
||||
var contentUrl: String?
|
||||
if let resource = content.resource as? HttpReferenceMediaResource {
|
||||
contentUrl = resource.url
|
||||
} else if let resource = content.resource as? WebFileReferenceMediaResource {
|
||||
contentUrl = resource.url
|
||||
}
|
||||
if let contentUrl = contentUrl, let url = URL(string: contentUrl) {
|
||||
if !url.lastPathComponent.isEmpty {
|
||||
fileName = url.lastPathComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var fileAttributes: [TelegramMediaFileAttribute] = []
|
||||
fileAttributes.append(.FileName(fileName: fileName))
|
||||
|
||||
if externalReference.type == "gif" {
|
||||
fileAttributes.append(.Animated)
|
||||
}
|
||||
|
||||
if let dimensions = externalReference.content?.dimensions {
|
||||
fileAttributes.append(.ImageSize(size: dimensions))
|
||||
if externalReference.type == "gif" {
|
||||
fileAttributes.append(.Video(duration: externalReference.content?.duration ?? 0.0, size: dimensions, flags: [], preloadSize: nil))
|
||||
}
|
||||
}
|
||||
|
||||
if externalReference.type == "audio" || externalReference.type == "voice" {
|
||||
fileAttributes.append(.Audio(isVoice: externalReference.type == "voice", duration: Int(Int32(externalReference.content?.duration ?? 0)), title: externalReference.title, performer: externalReference.description, waveform: nil))
|
||||
}
|
||||
|
||||
var randomId: Int64 = 0
|
||||
arc4random_buf(&randomId, 8)
|
||||
|
||||
let resource: TelegramMediaResource
|
||||
if peerId.namespace == Namespaces.Peer.SecretChat, let webResource = externalReference.content?.resource as? WebFileReferenceMediaResource {
|
||||
resource = webResource
|
||||
} else {
|
||||
resource = EmptyMediaResource()
|
||||
}
|
||||
|
||||
let file = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: randomId), partialReference: nil, resource: resource, previewRepresentations: previewRepresentations, videoThumbnails: videoThumbnails, immediateThumbnailData: nil, mimeType: externalReference.content?.mimeType ?? "application/binary", size: nil, attributes: fileAttributes)
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: file), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
} else {
|
||||
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
}
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
return .message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
case let .mapLocation(media, replyMarkup):
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
case let .contact(media, replyMarkup):
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
case let .invoice(media, replyMarkup):
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
}
|
||||
case let .text(text, entities, disableUrlPreview, previewParameters, replyMarkup):
|
||||
if let entities = entities {
|
||||
attributes.append(entities)
|
||||
}
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
if let previewParameters = previewParameters {
|
||||
attributes.append(previewParameters)
|
||||
}
|
||||
if disableUrlPreview {
|
||||
attributes.append(OutgoingContentInfoMessageAttribute(flags: [.disableLinkPreviews]))
|
||||
}
|
||||
return .message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
case let .mapLocation(media, replyMarkup):
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
case let .contact(media, replyMarkup):
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
case let .invoice(media, replyMarkup):
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
return .message(text: "", attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: media), replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
case let .webpage(text, entities, _, previewParameters, replyMarkup):
|
||||
if let entities = entities {
|
||||
attributes.append(entities)
|
||||
}
|
||||
if let replyMarkup = replyMarkup {
|
||||
attributes.append(replyMarkup)
|
||||
}
|
||||
if let previewParameters = previewParameters {
|
||||
attributes.append(previewParameters)
|
||||
}
|
||||
return .message(text: text, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, replyToStoryId: replyToStoryId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
|
||||
}
|
||||
}
|
||||
|
||||
@ -1061,7 +1061,8 @@ public class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
var needsReplyBackground = false
|
||||
var replyMarkup: ReplyMarkupMessageAttribute?
|
||||
|
||||
let availableContentWidth = min(120.0, max(60.0, params.width - params.leftInset - params.rightInset - max(imageSize.width, 160.0) - 20.0 - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left))
|
||||
var availableContentWidth = min(200.0, max(60.0, params.width - params.leftInset - params.rightInset - max(imageSize.width, 160.0) - 20.0 - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left))
|
||||
availableContentWidth -= 20.0
|
||||
|
||||
var ignoreForward = false
|
||||
if let forwardInfo = item.message.forwardInfo {
|
||||
|
||||
@ -37,14 +37,21 @@ private let channelIcon: UIImage = {
|
||||
})!.precomposed().withRenderingMode(.alwaysTemplate)
|
||||
}()
|
||||
|
||||
private let groupIcon: UIImage = {
|
||||
private func generateGroupIcon() -> UIImage {
|
||||
let sourceImage = UIImage(bundleImageName: "Chat/Input/Accessory Panels/PanelTextGroupIcon")!
|
||||
return generateImage(CGSize(width: sourceImage.size.width + 3.0, height: sourceImage.size.height + 4.0), rotatedContext: { size, context in
|
||||
return generateImage(CGSize(width: sourceImage.size.width, height: sourceImage.size.height + 4.0), rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
UIGraphicsPushContext(context)
|
||||
sourceImage.draw(at: CGPoint(x: 3.0, y: 1.0 - UIScreenPixel))
|
||||
sourceImage.draw(at: CGPoint(x: 0.0, y: 1.0 - UIScreenPixel))
|
||||
UIGraphicsPopContext()
|
||||
|
||||
//context.setFillColor(UIColor.white.cgColor)
|
||||
//context.fill(CGRect(origin: CGPoint(), size: size))
|
||||
})!.precomposed().withRenderingMode(.alwaysTemplate)
|
||||
}
|
||||
|
||||
private let groupIcon: UIImage = {
|
||||
return generateGroupIcon()
|
||||
}()
|
||||
|
||||
public class ChatMessageReplyInfoNode: ASDisplayNode {
|
||||
@ -286,6 +293,7 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
||||
titleString = rawTitleString
|
||||
} else {
|
||||
let rawTitleString = NSMutableAttributedString(attributedString: titleString)
|
||||
rawTitleString.append(NSAttributedString(string: "\u{200B}", font: titleFont, textColor: titleColor))
|
||||
rawTitleString.append(NSAttributedString(string: ">", attributes: [
|
||||
.attachment: groupIcon,
|
||||
.foregroundColor: titleColor,
|
||||
@ -603,7 +611,10 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
var size = CGSize(width: max(titleLayout.size.width + additionalTitleWidth - textInsets.left - textInsets.right, textLayout.size.width - textInsets.left - textInsets.right - textCutoutWidth) + leftInset + 6.0, height: titleLayout.size.height + textLayout.size.height - 2 * (textInsets.top + textInsets.bottom) + 2 * spacing)
|
||||
var size = CGSize()
|
||||
size.width = max(titleLayout.size.width + additionalTitleWidth - textInsets.left - textInsets.right, textLayout.size.width - textInsets.left - textInsets.right - textCutoutWidth) + leftInset + 6.0
|
||||
size.height = titleLayout.size.height + textLayout.size.height - 2 * (textInsets.top + textInsets.bottom) + 2 * spacing
|
||||
size.height += 2.0
|
||||
if isExpiredStory || isStory {
|
||||
size.width += 16.0
|
||||
}
|
||||
|
||||
@ -629,7 +629,8 @@ public class ChatMessageStickerItemNode: ChatMessageItemView {
|
||||
var replyInfoApply: (CGSize, (CGSize, Bool, ListViewItemUpdateAnimation) -> ChatMessageReplyInfoNode)?
|
||||
var replyMarkup: ReplyMarkupMessageAttribute?
|
||||
|
||||
var availableWidth = max(60.0, params.width - params.leftInset - params.rightInset - max(imageSize.width, 160.0) - 20.0 - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left)
|
||||
var availableWidth = min(200.0, max(60.0, params.width - params.leftInset - params.rightInset - max(imageSize.width, 160.0) - 20.0 - layoutConstants.bubble.edgeInset * 2.0 - avatarInset - layoutConstants.bubble.contentInsets.left))
|
||||
availableWidth -= 20.0
|
||||
if isEmoji {
|
||||
availableWidth -= 24.0
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user