mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-02 20:55:48 +00:00
Merge commit '9a414b9f09be0b56187a2c759d8c3b02ed6719f9'
This commit is contained in:
commit
0880e7864a
@ -14498,7 +14498,8 @@ Sorry for the inconvenience.";
|
|||||||
"Chat.Todo.ContextMenu.SectionsInfo" = "You're viewing actions for one task.\nYou can switch to actions for the list.";
|
"Chat.Todo.ContextMenu.SectionsInfo" = "You're viewing actions for one task.\nYou can switch to actions for the list.";
|
||||||
|
|
||||||
"Chat.Todo.PremiumRequired" = "Only [Telegram Premium]() subscribers can mark tasks as done.";
|
"Chat.Todo.PremiumRequired" = "Only [Telegram Premium]() subscribers can mark tasks as done.";
|
||||||
"Chat.Todo.CompletionLimited" = "%@ has restricted others from editing this to do list.";
|
"Chat.Todo.CompletionLimited" = "%@ has restricted others from editing this checklist.";
|
||||||
|
"Chat.Todo.CompletionLimitedForward" = "You can’t make changes to forwarded checklists.";
|
||||||
|
|
||||||
"Forward.ErrorTodoDisabledInChannels" = "Sorry, checklists can’t be forwarded to channels.";
|
"Forward.ErrorTodoDisabledInChannels" = "Sorry, checklists can’t be forwarded to channels.";
|
||||||
|
|
||||||
@ -14670,4 +14671,9 @@ Sorry for the inconvenience.";
|
|||||||
"Chat.Todo.Message.CompletedBy_1" = "%@ of {count} completed by {name}";
|
"Chat.Todo.Message.CompletedBy_1" = "%@ of {count} completed by {name}";
|
||||||
"Chat.Todo.Message.CompletedBy_any" = "%@ of {count} completed by {name}";
|
"Chat.Todo.Message.CompletedBy_any" = "%@ of {count} completed by {name}";
|
||||||
|
|
||||||
|
"Notification.StarGift.ReleasedBy" = "released by %@";
|
||||||
|
|
||||||
|
"Gift.View.ReleasedBy" = "released by %@";
|
||||||
|
"Gift.Unique.CollectibleBy" = "collectible %1$@ by %2$@";
|
||||||
|
|
||||||
"SendInviteLink.TextCallsRestrictedSendOneInviteLink" = "**%@** restricts calling them. You can send them an invite link to call instead.";
|
"SendInviteLink.TextCallsRestrictedSendOneInviteLink" = "**%@** restricts calling them. You can send them an invite link to call instead.";
|
||||||
|
|||||||
@ -943,8 +943,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[2109703795] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
|
dict[2109703795] = { return Api.SponsoredMessage.parse_sponsoredMessage($0) }
|
||||||
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
|
dict[1124938064] = { return Api.SponsoredMessageReportOption.parse_sponsoredMessageReportOption($0) }
|
||||||
dict[-963180333] = { return Api.SponsoredPeer.parse_sponsoredPeer($0) }
|
dict[-963180333] = { return Api.SponsoredPeer.parse_sponsoredPeer($0) }
|
||||||
dict[-970274264] = { return Api.StarGift.parse_starGift($0) }
|
dict[2139438098] = { return Api.StarGift.parse_starGift($0) }
|
||||||
dict[1678891913] = { return Api.StarGift.parse_starGiftUnique($0) }
|
dict[-164136786] = { return Api.StarGift.parse_starGiftUnique($0) }
|
||||||
dict[-650279524] = { return Api.StarGiftAttribute.parse_starGiftAttributeBackdrop($0) }
|
dict[-650279524] = { return Api.StarGiftAttribute.parse_starGiftAttributeBackdrop($0) }
|
||||||
dict[970559507] = { return Api.StarGiftAttribute.parse_starGiftAttributeModel($0) }
|
dict[970559507] = { return Api.StarGiftAttribute.parse_starGiftAttributeModel($0) }
|
||||||
dict[-524291476] = { return Api.StarGiftAttribute.parse_starGiftAttributeOriginalDetails($0) }
|
dict[-524291476] = { return Api.StarGiftAttribute.parse_starGiftAttributeOriginalDetails($0) }
|
||||||
@ -1432,7 +1432,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||||||
dict[-1779201615] = { return Api.payments.SavedStarGifts.parse_savedStarGifts($0) }
|
dict[-1779201615] = { return Api.payments.SavedStarGifts.parse_savedStarGifts($0) }
|
||||||
dict[377215243] = { return Api.payments.StarGiftUpgradePreview.parse_starGiftUpgradePreview($0) }
|
dict[377215243] = { return Api.payments.StarGiftUpgradePreview.parse_starGiftUpgradePreview($0) }
|
||||||
dict[-2069218660] = { return Api.payments.StarGiftWithdrawalUrl.parse_starGiftWithdrawalUrl($0) }
|
dict[-2069218660] = { return Api.payments.StarGiftWithdrawalUrl.parse_starGiftWithdrawalUrl($0) }
|
||||||
dict[-1877571094] = { return Api.payments.StarGifts.parse_starGifts($0) }
|
dict[785918357] = { return Api.payments.StarGifts.parse_starGifts($0) }
|
||||||
dict[-1551326360] = { return Api.payments.StarGifts.parse_starGiftsNotModified($0) }
|
dict[-1551326360] = { return Api.payments.StarGifts.parse_starGiftsNotModified($0) }
|
||||||
dict[961445665] = { return Api.payments.StarsRevenueAdsAccountUrl.parse_starsRevenueAdsAccountUrl($0) }
|
dict[961445665] = { return Api.payments.StarsRevenueAdsAccountUrl.parse_starsRevenueAdsAccountUrl($0) }
|
||||||
dict[1814066038] = { return Api.payments.StarsRevenueStats.parse_starsRevenueStats($0) }
|
dict[1814066038] = { return Api.payments.StarsRevenueStats.parse_starsRevenueStats($0) }
|
||||||
|
|||||||
@ -636,14 +636,14 @@ public extension Api {
|
|||||||
}
|
}
|
||||||
public extension Api {
|
public extension Api {
|
||||||
enum StarGift: TypeConstructorDescription {
|
enum StarGift: TypeConstructorDescription {
|
||||||
case starGift(flags: Int32, id: Int64, sticker: Api.Document, stars: Int64, availabilityRemains: Int32?, availabilityTotal: Int32?, availabilityResale: Int64?, convertStars: Int64, firstSaleDate: Int32?, lastSaleDate: Int32?, upgradeStars: Int64?, resellMinStars: Int64?, title: String?)
|
case starGift(flags: Int32, id: Int64, sticker: Api.Document, stars: Int64, availabilityRemains: Int32?, availabilityTotal: Int32?, availabilityResale: Int64?, convertStars: Int64, firstSaleDate: Int32?, lastSaleDate: Int32?, upgradeStars: Int64?, resellMinStars: Int64?, title: String?, releasedBy: Api.Peer?)
|
||||||
case starGiftUnique(flags: Int32, id: Int64, title: String, slug: String, num: Int32, ownerId: Api.Peer?, ownerName: String?, ownerAddress: String?, attributes: [Api.StarGiftAttribute], availabilityIssued: Int32, availabilityTotal: Int32, giftAddress: String?, resellStars: Int64?)
|
case starGiftUnique(flags: Int32, id: Int64, title: String, slug: String, num: Int32, ownerId: Api.Peer?, ownerName: String?, ownerAddress: String?, attributes: [Api.StarGiftAttribute], availabilityIssued: Int32, availabilityTotal: Int32, giftAddress: String?, resellStars: Int64?, releasedBy: Api.Peer?)
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let availabilityResale, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars, let resellMinStars, let title):
|
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let availabilityResale, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars, let resellMinStars, let title, let releasedBy):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-970274264)
|
buffer.appendInt32(2139438098)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
@ -658,10 +658,11 @@ public extension Api {
|
|||||||
if Int(flags) & Int(1 << 3) != 0 {serializeInt64(upgradeStars!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 3) != 0 {serializeInt64(upgradeStars!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt64(resellMinStars!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 4) != 0 {serializeInt64(resellMinStars!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 5) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 5) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 6) != 0 {releasedBy!.serialize(buffer, true)}
|
||||||
break
|
break
|
||||||
case .starGiftUnique(let flags, let id, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellStars):
|
case .starGiftUnique(let flags, let id, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellStars, let releasedBy):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(1678891913)
|
buffer.appendInt32(-164136786)
|
||||||
}
|
}
|
||||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||||
serializeInt64(id, buffer: buffer, boxed: false)
|
serializeInt64(id, buffer: buffer, boxed: false)
|
||||||
@ -680,16 +681,17 @@ public extension Api {
|
|||||||
serializeInt32(availabilityTotal, buffer: buffer, boxed: false)
|
serializeInt32(availabilityTotal, buffer: buffer, boxed: false)
|
||||||
if Int(flags) & Int(1 << 3) != 0 {serializeString(giftAddress!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 3) != 0 {serializeString(giftAddress!, buffer: buffer, boxed: false)}
|
||||||
if Int(flags) & Int(1 << 4) != 0 {serializeInt64(resellStars!, buffer: buffer, boxed: false)}
|
if Int(flags) & Int(1 << 4) != 0 {serializeInt64(resellStars!, buffer: buffer, boxed: false)}
|
||||||
|
if Int(flags) & Int(1 << 5) != 0 {releasedBy!.serialize(buffer, true)}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let availabilityResale, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars, let resellMinStars, let title):
|
case .starGift(let flags, let id, let sticker, let stars, let availabilityRemains, let availabilityTotal, let availabilityResale, let convertStars, let firstSaleDate, let lastSaleDate, let upgradeStars, let resellMinStars, let title, let releasedBy):
|
||||||
return ("starGift", [("flags", flags as Any), ("id", id as Any), ("sticker", sticker as Any), ("stars", stars as Any), ("availabilityRemains", availabilityRemains as Any), ("availabilityTotal", availabilityTotal as Any), ("availabilityResale", availabilityResale as Any), ("convertStars", convertStars as Any), ("firstSaleDate", firstSaleDate as Any), ("lastSaleDate", lastSaleDate as Any), ("upgradeStars", upgradeStars as Any), ("resellMinStars", resellMinStars as Any), ("title", title as Any)])
|
return ("starGift", [("flags", flags as Any), ("id", id as Any), ("sticker", sticker as Any), ("stars", stars as Any), ("availabilityRemains", availabilityRemains as Any), ("availabilityTotal", availabilityTotal as Any), ("availabilityResale", availabilityResale as Any), ("convertStars", convertStars as Any), ("firstSaleDate", firstSaleDate as Any), ("lastSaleDate", lastSaleDate as Any), ("upgradeStars", upgradeStars as Any), ("resellMinStars", resellMinStars as Any), ("title", title as Any), ("releasedBy", releasedBy as Any)])
|
||||||
case .starGiftUnique(let flags, let id, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellStars):
|
case .starGiftUnique(let flags, let id, let title, let slug, let num, let ownerId, let ownerName, let ownerAddress, let attributes, let availabilityIssued, let availabilityTotal, let giftAddress, let resellStars, let releasedBy):
|
||||||
return ("starGiftUnique", [("flags", flags as Any), ("id", id as Any), ("title", title as Any), ("slug", slug as Any), ("num", num as Any), ("ownerId", ownerId as Any), ("ownerName", ownerName as Any), ("ownerAddress", ownerAddress as Any), ("attributes", attributes as Any), ("availabilityIssued", availabilityIssued as Any), ("availabilityTotal", availabilityTotal as Any), ("giftAddress", giftAddress as Any), ("resellStars", resellStars as Any)])
|
return ("starGiftUnique", [("flags", flags as Any), ("id", id as Any), ("title", title as Any), ("slug", slug as Any), ("num", num as Any), ("ownerId", ownerId as Any), ("ownerName", ownerName as Any), ("ownerAddress", ownerAddress as Any), ("attributes", attributes as Any), ("availabilityIssued", availabilityIssued as Any), ("availabilityTotal", availabilityTotal as Any), ("giftAddress", giftAddress as Any), ("resellStars", resellStars as Any), ("releasedBy", releasedBy as Any)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -722,6 +724,10 @@ public extension Api {
|
|||||||
if Int(_1!) & Int(1 << 4) != 0 {_12 = reader.readInt64() }
|
if Int(_1!) & Int(1 << 4) != 0 {_12 = reader.readInt64() }
|
||||||
var _13: String?
|
var _13: String?
|
||||||
if Int(_1!) & Int(1 << 5) != 0 {_13 = parseString(reader) }
|
if Int(_1!) & Int(1 << 5) != 0 {_13 = parseString(reader) }
|
||||||
|
var _14: Api.Peer?
|
||||||
|
if Int(_1!) & Int(1 << 6) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_14 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||||
|
} }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
@ -735,8 +741,9 @@ public extension Api {
|
|||||||
let _c11 = (Int(_1!) & Int(1 << 3) == 0) || _11 != nil
|
let _c11 = (Int(_1!) & Int(1 << 3) == 0) || _11 != nil
|
||||||
let _c12 = (Int(_1!) & Int(1 << 4) == 0) || _12 != nil
|
let _c12 = (Int(_1!) & Int(1 << 4) == 0) || _12 != nil
|
||||||
let _c13 = (Int(_1!) & Int(1 << 5) == 0) || _13 != nil
|
let _c13 = (Int(_1!) & Int(1 << 5) == 0) || _13 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 {
|
let _c14 = (Int(_1!) & Int(1 << 6) == 0) || _14 != nil
|
||||||
return Api.StarGift.starGift(flags: _1!, id: _2!, sticker: _3!, stars: _4!, availabilityRemains: _5, availabilityTotal: _6, availabilityResale: _7, convertStars: _8!, firstSaleDate: _9, lastSaleDate: _10, upgradeStars: _11, resellMinStars: _12, title: _13)
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 {
|
||||||
|
return Api.StarGift.starGift(flags: _1!, id: _2!, sticker: _3!, stars: _4!, availabilityRemains: _5, availabilityTotal: _6, availabilityResale: _7, convertStars: _8!, firstSaleDate: _9, lastSaleDate: _10, upgradeStars: _11, resellMinStars: _12, title: _13, releasedBy: _14)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
@ -773,6 +780,10 @@ public extension Api {
|
|||||||
if Int(_1!) & Int(1 << 3) != 0 {_12 = parseString(reader) }
|
if Int(_1!) & Int(1 << 3) != 0 {_12 = parseString(reader) }
|
||||||
var _13: Int64?
|
var _13: Int64?
|
||||||
if Int(_1!) & Int(1 << 4) != 0 {_13 = reader.readInt64() }
|
if Int(_1!) & Int(1 << 4) != 0 {_13 = reader.readInt64() }
|
||||||
|
var _14: Api.Peer?
|
||||||
|
if Int(_1!) & Int(1 << 5) != 0 {if let signature = reader.readInt32() {
|
||||||
|
_14 = Api.parse(reader, signature: signature) as? Api.Peer
|
||||||
|
} }
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
let _c3 = _3 != nil
|
let _c3 = _3 != nil
|
||||||
@ -786,8 +797,9 @@ public extension Api {
|
|||||||
let _c11 = _11 != nil
|
let _c11 = _11 != nil
|
||||||
let _c12 = (Int(_1!) & Int(1 << 3) == 0) || _12 != nil
|
let _c12 = (Int(_1!) & Int(1 << 3) == 0) || _12 != nil
|
||||||
let _c13 = (Int(_1!) & Int(1 << 4) == 0) || _13 != nil
|
let _c13 = (Int(_1!) & Int(1 << 4) == 0) || _13 != nil
|
||||||
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 {
|
let _c14 = (Int(_1!) & Int(1 << 5) == 0) || _14 != nil
|
||||||
return Api.StarGift.starGiftUnique(flags: _1!, id: _2!, title: _3!, slug: _4!, num: _5!, ownerId: _6, ownerName: _7, ownerAddress: _8, attributes: _9!, availabilityIssued: _10!, availabilityTotal: _11!, giftAddress: _12, resellStars: _13)
|
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 {
|
||||||
|
return Api.StarGift.starGiftUnique(flags: _1!, id: _2!, title: _3!, slug: _4!, num: _5!, ownerId: _6, ownerName: _7, ownerAddress: _8, attributes: _9!, availabilityIssued: _10!, availabilityTotal: _11!, giftAddress: _12, resellStars: _13, releasedBy: _14)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -298,14 +298,14 @@ public extension Api.payments {
|
|||||||
}
|
}
|
||||||
public extension Api.payments {
|
public extension Api.payments {
|
||||||
enum StarGifts: TypeConstructorDescription {
|
enum StarGifts: TypeConstructorDescription {
|
||||||
case starGifts(hash: Int32, gifts: [Api.StarGift])
|
case starGifts(hash: Int32, gifts: [Api.StarGift], chats: [Api.Chat], users: [Api.User])
|
||||||
case starGiftsNotModified
|
case starGiftsNotModified
|
||||||
|
|
||||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||||
switch self {
|
switch self {
|
||||||
case .starGifts(let hash, let gifts):
|
case .starGifts(let hash, let gifts, let chats, let users):
|
||||||
if boxed {
|
if boxed {
|
||||||
buffer.appendInt32(-1877571094)
|
buffer.appendInt32(785918357)
|
||||||
}
|
}
|
||||||
serializeInt32(hash, buffer: buffer, boxed: false)
|
serializeInt32(hash, buffer: buffer, boxed: false)
|
||||||
buffer.appendInt32(481674261)
|
buffer.appendInt32(481674261)
|
||||||
@ -313,6 +313,16 @@ public extension Api.payments {
|
|||||||
for item in gifts {
|
for item in gifts {
|
||||||
item.serialize(buffer, true)
|
item.serialize(buffer, true)
|
||||||
}
|
}
|
||||||
|
buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(chats.count))
|
||||||
|
for item in chats {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}
|
||||||
|
buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(users.count))
|
||||||
|
for item in users {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}
|
||||||
break
|
break
|
||||||
case .starGiftsNotModified:
|
case .starGiftsNotModified:
|
||||||
if boxed {
|
if boxed {
|
||||||
@ -325,8 +335,8 @@ public extension Api.payments {
|
|||||||
|
|
||||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||||
switch self {
|
switch self {
|
||||||
case .starGifts(let hash, let gifts):
|
case .starGifts(let hash, let gifts, let chats, let users):
|
||||||
return ("starGifts", [("hash", hash as Any), ("gifts", gifts as Any)])
|
return ("starGifts", [("hash", hash as Any), ("gifts", gifts as Any), ("chats", chats as Any), ("users", users as Any)])
|
||||||
case .starGiftsNotModified:
|
case .starGiftsNotModified:
|
||||||
return ("starGiftsNotModified", [])
|
return ("starGiftsNotModified", [])
|
||||||
}
|
}
|
||||||
@ -339,10 +349,20 @@ public extension Api.payments {
|
|||||||
if let _ = reader.readInt32() {
|
if let _ = reader.readInt32() {
|
||||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarGift.self)
|
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.StarGift.self)
|
||||||
}
|
}
|
||||||
|
var _3: [Api.Chat]?
|
||||||
|
if let _ = reader.readInt32() {
|
||||||
|
_3 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Chat.self)
|
||||||
|
}
|
||||||
|
var _4: [Api.User]?
|
||||||
|
if let _ = reader.readInt32() {
|
||||||
|
_4 = Api.parseVector(reader, elementSignature: 0, elementType: Api.User.self)
|
||||||
|
}
|
||||||
let _c1 = _1 != nil
|
let _c1 = _1 != nil
|
||||||
let _c2 = _2 != nil
|
let _c2 = _2 != nil
|
||||||
if _c1 && _c2 {
|
let _c3 = _3 != nil
|
||||||
return Api.payments.StarGifts.starGifts(hash: _1!, gifts: _2!)
|
let _c4 = _4 != nil
|
||||||
|
if _c1 && _c2 && _c3 && _c4 {
|
||||||
|
return Api.payments.StarGifts.starGifts(hash: _1!, gifts: _2!, chats: _3!, users: _4!)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -122,7 +122,7 @@ final class AccountTaskManager {
|
|||||||
tasks.add(managedDisabledChannelStatusIconEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
tasks.add(managedDisabledChannelStatusIconEmoji(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||||
tasks.add(_internal_loadedStickerPack(postbox: self.stateManager.postbox, network: self.stateManager.network, reference: .iconTopicEmoji, forceActualized: true).start())
|
tasks.add(_internal_loadedStickerPack(postbox: self.stateManager.postbox, network: self.stateManager.network, reference: .iconTopicEmoji, forceActualized: true).start())
|
||||||
tasks.add(managedPeerColorUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
tasks.add(managedPeerColorUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||||
tasks.add(managedStarGiftsUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
tasks.add(managedStarGiftsUpdates(postbox: self.stateManager.postbox, network: self.stateManager.network, accountPeerId: self.stateManager.accountPeerId).start())
|
||||||
|
|
||||||
self.managedTopReactionsDisposable.set(managedTopReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
self.managedTopReactionsDisposable.set(managedTopReactions(postbox: self.stateManager.postbox, network: self.stateManager.network).start())
|
||||||
|
|
||||||
|
|||||||
@ -354,7 +354,8 @@ func managedUniqueStarGifts(accountPeerId: PeerId, postbox: Postbox, network: Ne
|
|||||||
],
|
],
|
||||||
availability: StarGift.UniqueGift.Availability(issued: 0, total: 0),
|
availability: StarGift.UniqueGift.Availability(issued: 0, total: 0),
|
||||||
giftAddress: nil,
|
giftAddress: nil,
|
||||||
resellStars: nil
|
resellStars: nil,
|
||||||
|
releasedBy: nil
|
||||||
)
|
)
|
||||||
if let entry = CodableEntry(RecentStarGiftItem(gift)) {
|
if let entry = CodableEntry(RecentStarGiftItem(gift)) {
|
||||||
items.append(OrderedItemListEntry(id: RecentStarGiftItemId(id).rawValue, contents: entry))
|
items.append(OrderedItemListEntry(id: RecentStarGiftItemId(id).rawValue, contents: entry))
|
||||||
|
|||||||
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
|||||||
|
|
||||||
public class Serialization: NSObject, MTSerialization {
|
public class Serialization: NSObject, MTSerialization {
|
||||||
public func currentLayer() -> UInt {
|
public func currentLayer() -> UInt {
|
||||||
return 206
|
return 207
|
||||||
}
|
}
|
||||||
|
|
||||||
public func parseMessage(_ data: Data!) -> Any! {
|
public func parseMessage(_ data: Data!) -> Any! {
|
||||||
|
|||||||
@ -869,7 +869,7 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||||||
return [peerId]
|
return [peerId]
|
||||||
case let .prizeStars(_, _, boostPeerId, _, _):
|
case let .prizeStars(_, _, boostPeerId, _, _):
|
||||||
return boostPeerId.flatMap { [$0] } ?? []
|
return boostPeerId.flatMap { [$0] } ?? []
|
||||||
case let .starGift(_, _, _, _, _, _, _, _, _, _, _, _, peerId, senderId, _):
|
case let .starGift(gift, _, _, _, _, _, _, _, _, _, _, _, peerId, senderId, _):
|
||||||
var peerIds: [PeerId] = []
|
var peerIds: [PeerId] = []
|
||||||
if let peerId {
|
if let peerId {
|
||||||
peerIds.append(peerId)
|
peerIds.append(peerId)
|
||||||
@ -877,8 +877,11 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||||||
if let senderId {
|
if let senderId {
|
||||||
peerIds.append(senderId)
|
peerIds.append(senderId)
|
||||||
}
|
}
|
||||||
|
if let releasedBy = gift.releasedBy {
|
||||||
|
peerIds.append(releasedBy)
|
||||||
|
}
|
||||||
return peerIds
|
return peerIds
|
||||||
case let .starGiftUnique(_, _, _, _, _, _, _, peerId, senderId, _, _, _, _):
|
case let .starGiftUnique(gift, _, _, _, _, _, _, peerId, senderId, _, _, _, _):
|
||||||
var peerIds: [PeerId] = []
|
var peerIds: [PeerId] = []
|
||||||
if let peerId {
|
if let peerId {
|
||||||
peerIds.append(peerId)
|
peerIds.append(peerId)
|
||||||
@ -886,6 +889,9 @@ public enum TelegramMediaActionType: PostboxCoding, Equatable {
|
|||||||
if let senderId {
|
if let senderId {
|
||||||
peerIds.append(senderId)
|
peerIds.append(senderId)
|
||||||
}
|
}
|
||||||
|
if let releasedBy = gift.releasedBy {
|
||||||
|
peerIds.append(releasedBy)
|
||||||
|
}
|
||||||
return peerIds
|
return peerIds
|
||||||
case let .conferenceCall(conferenceCall):
|
case let .conferenceCall(conferenceCall):
|
||||||
return conferenceCall.otherParticipants
|
return conferenceCall.otherParticipants
|
||||||
|
|||||||
@ -54,6 +54,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
case soldOut
|
case soldOut
|
||||||
case flags
|
case flags
|
||||||
case upgradeStars
|
case upgradeStars
|
||||||
|
case releasedBy
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Availability: Equatable, Codable, PostboxCoding {
|
public struct Availability: Equatable, Codable, PostboxCoding {
|
||||||
@ -149,8 +150,9 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
public let soldOut: SoldOut?
|
public let soldOut: SoldOut?
|
||||||
public let flags: Flags
|
public let flags: Flags
|
||||||
public let upgradeStars: Int64?
|
public let upgradeStars: Int64?
|
||||||
|
public let releasedBy: EnginePeer.Id?
|
||||||
|
|
||||||
public init(id: Int64, title: String?, file: TelegramMediaFile, price: Int64, convertStars: Int64, availability: Availability?, soldOut: SoldOut?, flags: Flags, upgradeStars: Int64?) {
|
public init(id: Int64, title: String?, file: TelegramMediaFile, price: Int64, convertStars: Int64, availability: Availability?, soldOut: SoldOut?, flags: Flags, upgradeStars: Int64?, releasedBy: EnginePeer.Id?) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.title = title
|
self.title = title
|
||||||
self.file = file
|
self.file = file
|
||||||
@ -160,6 +162,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
self.soldOut = soldOut
|
self.soldOut = soldOut
|
||||||
self.flags = flags
|
self.flags = flags
|
||||||
self.upgradeStars = upgradeStars
|
self.upgradeStars = upgradeStars
|
||||||
|
self.releasedBy = releasedBy
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
@ -179,6 +182,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
self.soldOut = try container.decodeIfPresent(SoldOut.self, forKey: .soldOut)
|
self.soldOut = try container.decodeIfPresent(SoldOut.self, forKey: .soldOut)
|
||||||
self.flags = Flags(rawValue: try container .decodeIfPresent(Int32.self, forKey: .flags) ?? 0)
|
self.flags = Flags(rawValue: try container .decodeIfPresent(Int32.self, forKey: .flags) ?? 0)
|
||||||
self.upgradeStars = try container.decodeIfPresent(Int64.self, forKey: .upgradeStars)
|
self.upgradeStars = try container.decodeIfPresent(Int64.self, forKey: .upgradeStars)
|
||||||
|
self.releasedBy = try container.decodeIfPresent(EnginePeer.Id.self, forKey: .releasedBy)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
@ -191,6 +195,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
self.soldOut = decoder.decodeObjectForKey(CodingKeys.soldOut.rawValue, decoder: { StarGift.Gift.SoldOut(decoder: $0) }) as? StarGift.Gift.SoldOut
|
self.soldOut = decoder.decodeObjectForKey(CodingKeys.soldOut.rawValue, decoder: { StarGift.Gift.SoldOut(decoder: $0) }) as? StarGift.Gift.SoldOut
|
||||||
self.flags = Flags(rawValue: decoder.decodeInt32ForKey(CodingKeys.flags.rawValue, orElse: 0))
|
self.flags = Flags(rawValue: decoder.decodeInt32ForKey(CodingKeys.flags.rawValue, orElse: 0))
|
||||||
self.upgradeStars = decoder.decodeOptionalInt64ForKey(CodingKeys.upgradeStars.rawValue)
|
self.upgradeStars = decoder.decodeOptionalInt64ForKey(CodingKeys.upgradeStars.rawValue)
|
||||||
|
self.releasedBy = decoder.decodeOptionalInt64ForKey(CodingKeys.releasedBy.rawValue).flatMap { EnginePeer.Id($0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -209,6 +214,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
try container.encodeIfPresent(self.soldOut, forKey: .soldOut)
|
try container.encodeIfPresent(self.soldOut, forKey: .soldOut)
|
||||||
try container.encode(self.flags.rawValue, forKey: .flags)
|
try container.encode(self.flags.rawValue, forKey: .flags)
|
||||||
try container.encodeIfPresent(self.upgradeStars, forKey: .upgradeStars)
|
try container.encodeIfPresent(self.upgradeStars, forKey: .upgradeStars)
|
||||||
|
try container.encodeIfPresent(self.releasedBy, forKey: .releasedBy)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -237,6 +243,11 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
} else {
|
} else {
|
||||||
encoder.encodeNil(forKey: CodingKeys.upgradeStars.rawValue)
|
encoder.encodeNil(forKey: CodingKeys.upgradeStars.rawValue)
|
||||||
}
|
}
|
||||||
|
if let releasedBy = self.releasedBy {
|
||||||
|
encoder.encodeInt64(releasedBy.toInt64(), forKey: CodingKeys.releasedBy.rawValue)
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: CodingKeys.releasedBy.rawValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,6 +264,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
case availability
|
case availability
|
||||||
case giftAddress
|
case giftAddress
|
||||||
case resellStars
|
case resellStars
|
||||||
|
case releasedBy
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Attribute: Equatable, Codable, PostboxCoding {
|
public enum Attribute: Equatable, Codable, PostboxCoding {
|
||||||
@ -506,8 +518,9 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
public let availability: Availability
|
public let availability: Availability
|
||||||
public let giftAddress: String?
|
public let giftAddress: String?
|
||||||
public let resellStars: Int64?
|
public let resellStars: Int64?
|
||||||
|
public let releasedBy: EnginePeer.Id?
|
||||||
|
|
||||||
public init(id: Int64, title: String, number: Int32, slug: String, owner: Owner, attributes: [Attribute], availability: Availability, giftAddress: String?, resellStars: Int64?) {
|
public init(id: Int64, title: String, number: Int32, slug: String, owner: Owner, attributes: [Attribute], availability: Availability, giftAddress: String?, resellStars: Int64?, releasedBy: EnginePeer.Id?) {
|
||||||
self.id = id
|
self.id = id
|
||||||
self.title = title
|
self.title = title
|
||||||
self.number = number
|
self.number = number
|
||||||
@ -517,6 +530,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
self.availability = availability
|
self.availability = availability
|
||||||
self.giftAddress = giftAddress
|
self.giftAddress = giftAddress
|
||||||
self.resellStars = resellStars
|
self.resellStars = resellStars
|
||||||
|
self.releasedBy = releasedBy
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
@ -538,6 +552,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
self.availability = try container.decode(UniqueGift.Availability.self, forKey: .availability)
|
self.availability = try container.decode(UniqueGift.Availability.self, forKey: .availability)
|
||||||
self.giftAddress = try container.decodeIfPresent(String.self, forKey: .giftAddress)
|
self.giftAddress = try container.decodeIfPresent(String.self, forKey: .giftAddress)
|
||||||
self.resellStars = try container.decodeIfPresent(Int64.self, forKey: .resellStars)
|
self.resellStars = try container.decodeIfPresent(Int64.self, forKey: .resellStars)
|
||||||
|
self.releasedBy = try container.decodeIfPresent(EnginePeer.Id.self, forKey: .releasedBy)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
@ -558,6 +573,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
self.availability = decoder.decodeObjectForKey(CodingKeys.availability.rawValue, decoder: { UniqueGift.Availability(decoder: $0) }) as! UniqueGift.Availability
|
self.availability = decoder.decodeObjectForKey(CodingKeys.availability.rawValue, decoder: { UniqueGift.Availability(decoder: $0) }) as! UniqueGift.Availability
|
||||||
self.giftAddress = decoder.decodeOptionalStringForKey(CodingKeys.giftAddress.rawValue)
|
self.giftAddress = decoder.decodeOptionalStringForKey(CodingKeys.giftAddress.rawValue)
|
||||||
self.resellStars = decoder.decodeOptionalInt64ForKey(CodingKeys.resellStars.rawValue)
|
self.resellStars = decoder.decodeOptionalInt64ForKey(CodingKeys.resellStars.rawValue)
|
||||||
|
self.releasedBy = decoder.decodeOptionalInt64ForKey(CodingKeys.releasedBy.rawValue).flatMap { EnginePeer.Id($0) }
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
@ -578,6 +594,7 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
try container.encode(self.availability, forKey: .availability)
|
try container.encode(self.availability, forKey: .availability)
|
||||||
try container.encodeIfPresent(self.giftAddress, forKey: .giftAddress)
|
try container.encodeIfPresent(self.giftAddress, forKey: .giftAddress)
|
||||||
try container.encodeIfPresent(self.resellStars, forKey: .resellStars)
|
try container.encodeIfPresent(self.resellStars, forKey: .resellStars)
|
||||||
|
try container.encodeIfPresent(self.releasedBy, forKey: .releasedBy)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -605,6 +622,11 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
} else {
|
} else {
|
||||||
encoder.encodeNil(forKey: CodingKeys.resellStars.rawValue)
|
encoder.encodeNil(forKey: CodingKeys.resellStars.rawValue)
|
||||||
}
|
}
|
||||||
|
if let releasedBy = self.releasedBy {
|
||||||
|
encoder.encodeInt64(releasedBy.toInt64(), forKey: CodingKeys.releasedBy.rawValue)
|
||||||
|
} else {
|
||||||
|
encoder.encodeNil(forKey: CodingKeys.releasedBy.rawValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func withResellStars(_ resellStars: Int64?) -> UniqueGift {
|
public func withResellStars(_ resellStars: Int64?) -> UniqueGift {
|
||||||
@ -617,7 +639,8 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
attributes: self.attributes,
|
attributes: self.attributes,
|
||||||
availability: self.availability,
|
availability: self.availability,
|
||||||
giftAddress: self.giftAddress,
|
giftAddress: self.giftAddress,
|
||||||
resellStars: resellStars
|
resellStars: resellStars,
|
||||||
|
releasedBy: self.releasedBy
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -683,10 +706,21 @@ public enum StarGift: Equatable, Codable, PostboxCoding {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension StarGift {
|
||||||
|
var releasedBy: EnginePeer.Id? {
|
||||||
|
switch self {
|
||||||
|
case let .generic(gift):
|
||||||
|
return gift.releasedBy
|
||||||
|
case let .unique(gift):
|
||||||
|
return gift.releasedBy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extension StarGift {
|
extension StarGift {
|
||||||
init?(apiStarGift: Api.StarGift) {
|
init?(apiStarGift: Api.StarGift) {
|
||||||
switch apiStarGift {
|
switch apiStarGift {
|
||||||
case let .starGift(apiFlags, id, sticker, stars, availabilityRemains, availabilityTotal, availabilityResale, convertStars, firstSale, lastSale, upgradeStars, minResaleStars, title):
|
case let .starGift(apiFlags, id, sticker, stars, availabilityRemains, availabilityTotal, availabilityResale, convertStars, firstSale, lastSale, upgradeStars, minResaleStars, title, releasedBy):
|
||||||
var flags = StarGift.Gift.Flags()
|
var flags = StarGift.Gift.Flags()
|
||||||
if (apiFlags & (1 << 2)) != 0 {
|
if (apiFlags & (1 << 2)) != 0 {
|
||||||
flags.insert(.isBirthdayGift)
|
flags.insert(.isBirthdayGift)
|
||||||
@ -708,8 +742,8 @@ extension StarGift {
|
|||||||
guard let file = telegramMediaFileFromApiDocument(sticker, altDocuments: nil) else {
|
guard let file = telegramMediaFileFromApiDocument(sticker, altDocuments: nil) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
self = .generic(StarGift.Gift(id: id, title: title, file: file, price: stars, convertStars: convertStars, availability: availability, soldOut: soldOut, flags: flags, upgradeStars: upgradeStars))
|
self = .generic(StarGift.Gift(id: id, title: title, file: file, price: stars, convertStars: convertStars, availability: availability, soldOut: soldOut, flags: flags, upgradeStars: upgradeStars, releasedBy: releasedBy?.peerId))
|
||||||
case let .starGiftUnique(_, id, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal, giftAddress, reselltars):
|
case let .starGiftUnique(_, id, title, slug, num, ownerPeerId, ownerName, ownerAddress, attributes, availabilityIssued, availabilityTotal, giftAddress, resellStars, releasedBy):
|
||||||
let owner: StarGift.UniqueGift.Owner
|
let owner: StarGift.UniqueGift.Owner
|
||||||
if let ownerAddress {
|
if let ownerAddress {
|
||||||
owner = .address(ownerAddress)
|
owner = .address(ownerAddress)
|
||||||
@ -720,7 +754,7 @@ extension StarGift {
|
|||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
self = .unique(StarGift.UniqueGift(id: id, title: title, number: num, slug: slug, owner: owner, attributes: attributes.compactMap { UniqueGift.Attribute(apiAttribute: $0) }, availability: UniqueGift.Availability(issued: availabilityIssued, total: availabilityTotal), giftAddress: giftAddress, resellStars: reselltars))
|
self = .unique(StarGift.UniqueGift(id: id, title: title, number: num, slug: slug, owner: owner, attributes: attributes.compactMap { UniqueGift.Attribute(apiAttribute: $0) }, availability: UniqueGift.Availability(issued: availabilityIssued, total: availabilityTotal), giftAddress: giftAddress, resellStars: resellStars, releasedBy: releasedBy?.peerId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -739,7 +773,7 @@ func _internal_cachedStarGifts(postbox: Postbox) -> Signal<StarGiftsList?, NoErr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func _internal_keepCachedStarGiftsUpdated(postbox: Postbox, network: Network) -> Signal<Never, NoError> {
|
func _internal_keepCachedStarGiftsUpdated(postbox: Postbox, network: Network, accountPeerId: EnginePeer.Id) -> Signal<Never, NoError> {
|
||||||
let updateSignal = _internal_cachedStarGifts(postbox: postbox)
|
let updateSignal = _internal_cachedStarGifts(postbox: postbox)
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> mapToSignal { list -> Signal<Never, NoError> in
|
|> mapToSignal { list -> Signal<Never, NoError> in
|
||||||
@ -755,7 +789,10 @@ func _internal_keepCachedStarGiftsUpdated(postbox: Postbox, network: Network) ->
|
|||||||
|
|
||||||
return postbox.transaction { transaction in
|
return postbox.transaction { transaction in
|
||||||
switch result {
|
switch result {
|
||||||
case let .starGifts(hash, gifts):
|
case let .starGifts(hash, gifts, chats, users):
|
||||||
|
let parsedPeers = AccumulatedPeers(transaction: transaction, chats: chats, users: users)
|
||||||
|
updatePeers(transaction: transaction, accountPeerId: accountPeerId, peers: parsedPeers)
|
||||||
|
|
||||||
let starGiftsLists = StarGiftsList(items: gifts.compactMap { StarGift(apiStarGift: $0) }, hashValue: hash)
|
let starGiftsLists = StarGiftsList(items: gifts.compactMap { StarGift(apiStarGift: $0) }, hashValue: hash)
|
||||||
transaction.setPreferencesEntry(key: PreferencesKeys.starGifts(), value: PreferencesEntry(starGiftsLists))
|
transaction.setPreferencesEntry(key: PreferencesKeys.starGifts(), value: PreferencesEntry(starGiftsLists))
|
||||||
case .starGiftsNotModified:
|
case .starGiftsNotModified:
|
||||||
@ -769,8 +806,8 @@ func _internal_keepCachedStarGiftsUpdated(postbox: Postbox, network: Network) ->
|
|||||||
return updateSignal
|
return updateSignal
|
||||||
}
|
}
|
||||||
|
|
||||||
func managedStarGiftsUpdates(postbox: Postbox, network: Network) -> Signal<Never, NoError> {
|
func managedStarGiftsUpdates(postbox: Postbox, network: Network, accountPeerId: EnginePeer.Id) -> Signal<Never, NoError> {
|
||||||
let poll = _internal_keepCachedStarGiftsUpdated(postbox: postbox, network: network)
|
let poll = _internal_keepCachedStarGiftsUpdated(postbox: postbox, network: network, accountPeerId: accountPeerId)
|
||||||
return (poll |> then(.complete() |> suspendAwareDelay(1.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
return (poll |> then(.complete() |> suspendAwareDelay(1.0 * 60.0 * 60.0, queue: Queue.concurrentDefaultQueue()))) |> restart
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -114,7 +114,7 @@ public extension TelegramEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func keepStarGiftsUpdated() -> Signal<Never, NoError> {
|
public func keepStarGiftsUpdated() -> Signal<Never, NoError> {
|
||||||
return _internal_keepCachedStarGiftsUpdated(postbox: self.account.postbox, network: self.account.network)
|
return _internal_keepCachedStarGiftsUpdated(postbox: self.account.postbox, network: self.account.network, accountPeerId: self.account.peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func convertStarGift(reference: StarGiftReference) -> Signal<Never, NoError> {
|
public func convertStarGift(reference: StarGiftReference) -> Signal<Never, NoError> {
|
||||||
|
|||||||
@ -56,6 +56,9 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
private let ribbonBackgroundNode: ASImageNode
|
private let ribbonBackgroundNode: ASImageNode
|
||||||
private let ribbonTextNode: TextNode
|
private let ribbonTextNode: TextNode
|
||||||
|
|
||||||
|
private let creatorButtonNode: HighlightTrackingButtonNode
|
||||||
|
private let creatorButtonTitleNode: TextNode
|
||||||
|
|
||||||
private var shimmerEffectNode: ShimmerEffectForegroundNode?
|
private var shimmerEffectNode: ShimmerEffectForegroundNode?
|
||||||
private let buttonNode: HighlightTrackingButtonNode
|
private let buttonNode: HighlightTrackingButtonNode
|
||||||
private let buttonStarsNode: PremiumStarsNode
|
private let buttonStarsNode: PremiumStarsNode
|
||||||
@ -152,17 +155,17 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
self.symbolValueTextNode = TextNode()
|
self.symbolValueTextNode = TextNode()
|
||||||
self.symbolValueTextNode.isUserInteractionEnabled = false
|
self.symbolValueTextNode.isUserInteractionEnabled = false
|
||||||
self.symbolValueTextNode.displaysAsynchronously = false
|
self.symbolValueTextNode.displaysAsynchronously = false
|
||||||
|
|
||||||
self.buttonNode = HighlightTrackingButtonNode()
|
|
||||||
self.buttonNode.clipsToBounds = true
|
|
||||||
self.buttonNode.cornerRadius = 17.0
|
|
||||||
|
|
||||||
self.placeholderNode = StickerShimmerEffectNode()
|
self.placeholderNode = StickerShimmerEffectNode()
|
||||||
self.placeholderNode.isUserInteractionEnabled = false
|
self.placeholderNode.isUserInteractionEnabled = false
|
||||||
self.placeholderNode.alpha = 0.75
|
self.placeholderNode.alpha = 0.75
|
||||||
|
|
||||||
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
self.animationNode = DefaultAnimatedStickerNodeImpl()
|
||||||
|
|
||||||
|
self.buttonNode = HighlightTrackingButtonNode()
|
||||||
|
self.buttonNode.clipsToBounds = true
|
||||||
|
self.buttonNode.cornerRadius = 17.0
|
||||||
|
|
||||||
self.buttonStarsNode = PremiumStarsNode()
|
self.buttonStarsNode = PremiumStarsNode()
|
||||||
|
|
||||||
self.buttonContentNode = ASDisplayNode()
|
self.buttonContentNode = ASDisplayNode()
|
||||||
@ -171,6 +174,13 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
self.buttonTitleNode = TextNode()
|
self.buttonTitleNode = TextNode()
|
||||||
self.buttonTitleNode.displaysAsynchronously = false
|
self.buttonTitleNode.displaysAsynchronously = false
|
||||||
|
|
||||||
|
self.creatorButtonNode = HighlightTrackingButtonNode()
|
||||||
|
self.creatorButtonNode.clipsToBounds = true
|
||||||
|
self.creatorButtonNode.cornerRadius = 9.0
|
||||||
|
|
||||||
|
self.creatorButtonTitleNode = TextNode()
|
||||||
|
self.creatorButtonTitleNode.displaysAsynchronously = false
|
||||||
|
|
||||||
self.ribbonBackgroundNode = ASImageNode()
|
self.ribbonBackgroundNode = ASImageNode()
|
||||||
self.ribbonBackgroundNode.displaysAsynchronously = false
|
self.ribbonBackgroundNode.displaysAsynchronously = false
|
||||||
|
|
||||||
@ -196,9 +206,12 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
self.addSubnode(self.buttonNode)
|
self.addSubnode(self.buttonNode)
|
||||||
self.buttonNode.addSubnode(self.buttonStarsNode)
|
self.buttonNode.addSubnode(self.buttonStarsNode)
|
||||||
self.buttonNode.addSubnode(self.buttonContentNode)
|
self.buttonNode.addSubnode(self.buttonContentNode)
|
||||||
|
|
||||||
self.buttonContentNode.addSubnode(self.buttonTitleNode)
|
self.buttonContentNode.addSubnode(self.buttonTitleNode)
|
||||||
|
|
||||||
|
self.addSubnode(self.creatorButtonNode)
|
||||||
|
self.creatorButtonNode.addSubnode(self.creatorButtonTitleNode)
|
||||||
|
|
||||||
self.addSubnode(self.ribbonBackgroundNode)
|
self.addSubnode(self.ribbonBackgroundNode)
|
||||||
self.addSubnode(self.ribbonTextNode)
|
self.addSubnode(self.ribbonTextNode)
|
||||||
|
|
||||||
@ -213,8 +226,20 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
||||||
|
|
||||||
|
self.creatorButtonNode.highligthedChanged = { [weak self] highlighted in
|
||||||
|
if let strongSelf = self {
|
||||||
|
if highlighted {
|
||||||
|
strongSelf.creatorButtonNode.layer.removeAnimation(forKey: "opacity")
|
||||||
|
strongSelf.creatorButtonNode.alpha = 0.4
|
||||||
|
} else {
|
||||||
|
strongSelf.creatorButtonNode.alpha = 1.0
|
||||||
|
strongSelf.creatorButtonNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.creatorButtonNode.addTarget(self, action: #selector(self.creatorButtonPressed), forControlEvents: .touchUpInside)
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init?(coder aDecoder: NSCoder) {
|
required public init?(coder aDecoder: NSCoder) {
|
||||||
@ -239,6 +264,31 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
self.maskView?.addSubview(maskOverlayView)
|
self.maskView?.addSubview(maskOverlayView)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc private func creatorButtonPressed() {
|
||||||
|
guard let item = self.item else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var releasedBy: EnginePeer.Id?
|
||||||
|
for media in item.message.media {
|
||||||
|
if let action = media as? TelegramMediaAction {
|
||||||
|
switch action.action {
|
||||||
|
case let .starGift(gift, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||||
|
releasedBy = gift.releasedBy
|
||||||
|
case let .starGiftUnique(gift, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||||
|
releasedBy = gift.releasedBy
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guard let releasedBy, let peer = item.message.peers[releasedBy] else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
item.controllerInteraction.openPeer(EnginePeer(peer), .chat(textInputState: nil, subject: nil, peekData: nil), nil, .default)
|
||||||
|
}
|
||||||
|
|
||||||
@objc private func buttonPressed() {
|
@objc private func buttonPressed() {
|
||||||
guard let item = self.item else {
|
guard let item = self.item else {
|
||||||
return
|
return
|
||||||
@ -330,6 +380,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
let makeMeasureTextLayout = TextNode.asyncLayout(nil)
|
let makeMeasureTextLayout = TextNode.asyncLayout(nil)
|
||||||
let makeMoreTextLayout = TextNode.asyncLayout(self.moreTextNode)
|
let makeMoreTextLayout = TextNode.asyncLayout(self.moreTextNode)
|
||||||
|
|
||||||
|
let makeCreatorButtonTitleLayout = TextNode.asyncLayout(self.creatorButtonTitleNode)
|
||||||
|
|
||||||
let makeModelTitleLayout = TextNode.asyncLayout(self.modelTitleTextNode)
|
let makeModelTitleLayout = TextNode.asyncLayout(self.modelTitleTextNode)
|
||||||
let makeModelValueLayout = TextNode.asyncLayout(self.modelValueTextNode)
|
let makeModelValueLayout = TextNode.asyncLayout(self.modelValueTextNode)
|
||||||
let makeBackdropTitleLayout = TextNode.asyncLayout(self.backdropTitleTextNode)
|
let makeBackdropTitleLayout = TextNode.asyncLayout(self.backdropTitleTextNode)
|
||||||
@ -373,6 +425,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
var textSpacing: CGFloat = 0.0
|
var textSpacing: CGFloat = 0.0
|
||||||
var isStarGift = false
|
var isStarGift = false
|
||||||
|
|
||||||
|
var creatorButtonTitle = ""
|
||||||
|
|
||||||
var modelTitle: String?
|
var modelTitle: String?
|
||||||
var modelValue: String?
|
var modelValue: String?
|
||||||
var backdropTitle: String?
|
var backdropTitle: String?
|
||||||
@ -494,6 +548,10 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
}
|
}
|
||||||
case let .starGift(gift, convertStars, giftText, giftEntities, _, savedToProfile, converted, upgraded, canUpgrade, upgradeStars, isRefunded, _, channelPeerId, senderPeerId, _):
|
case let .starGift(gift, convertStars, giftText, giftEntities, _, savedToProfile, converted, upgraded, canUpgrade, upgradeStars, isRefunded, _, channelPeerId, senderPeerId, _):
|
||||||
if case let .generic(gift) = gift {
|
if case let .generic(gift) = gift {
|
||||||
|
if let releasedBy = gift.releasedBy, let peer = item.message.peers[releasedBy], let addressName = peer.addressName {
|
||||||
|
creatorButtonTitle = item.presentationData.strings.Notification_StarGift_ReleasedBy("**@\(addressName)**").string
|
||||||
|
}
|
||||||
|
|
||||||
isStarGift = true
|
isStarGift = true
|
||||||
var authorName = item.message.author.flatMap { EnginePeer($0) }?.compactDisplayTitle ?? ""
|
var authorName = item.message.author.flatMap { EnginePeer($0) }?.compactDisplayTitle ?? ""
|
||||||
|
|
||||||
@ -763,7 +821,22 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: buttonTitle, font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: buttonTitle, font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
let (ribbonTextLayout, ribbonTextApply) = makeRibbonTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: ribbonTitle, font: Font.semibold(11.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
let (ribbonTextLayout, ribbonTextApply) = makeRibbonTextLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: ribbonTitle, font: Font.semibold(11.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
|
let creatorButtonAttributedString = parseMarkdownIntoAttributedString(creatorButtonTitle, attributes: MarkdownAttributes(
|
||||||
|
body: MarkdownAttributeSet(font: Font.regular(12.0), textColor: primaryTextColor),
|
||||||
|
bold: MarkdownAttributeSet(font: Font.semibold(12.0), textColor: primaryTextColor),
|
||||||
|
link: MarkdownAttributeSet(font: Font.regular(12.0), textColor: primaryTextColor),
|
||||||
|
linkAttribute: { url in
|
||||||
|
return ("URL", url)
|
||||||
|
}
|
||||||
|
), textAlignment: .center)
|
||||||
|
|
||||||
|
let (creatorButtonTitleLayout, creatorButtonTitleApply) = makeCreatorButtonTitleLayout(TextNodeLayoutArguments(attributedString: creatorButtonAttributedString, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: giftSize.width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||||
|
|
||||||
|
if !creatorButtonTitle.isEmpty {
|
||||||
|
textSpacing += 28.0
|
||||||
|
}
|
||||||
|
|
||||||
giftSize.height = titleLayout.size.height + textSpacing + clippedTextHeight + 164.0
|
giftSize.height = titleLayout.size.height + textSpacing + clippedTextHeight + 164.0
|
||||||
|
|
||||||
if let _ = modelTitle {
|
if let _ = modelTitle {
|
||||||
@ -848,6 +921,9 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
|
|
||||||
strongSelf.buttonNode.isHidden = buttonTitle.isEmpty
|
strongSelf.buttonNode.isHidden = buttonTitle.isEmpty
|
||||||
strongSelf.buttonTitleNode.isHidden = buttonTitle.isEmpty
|
strongSelf.buttonTitleNode.isHidden = buttonTitle.isEmpty
|
||||||
|
|
||||||
|
strongSelf.creatorButtonNode.isHidden = creatorButtonTitle.isEmpty
|
||||||
|
strongSelf.creatorButtonTitleNode.isHidden = creatorButtonTitle.isEmpty
|
||||||
|
|
||||||
if strongSelf.item == nil && !isStoryEntity {
|
if strongSelf.item == nil && !isStoryEntity {
|
||||||
strongSelf.animationNode.started = { [weak self] in
|
strongSelf.animationNode.started = { [weak self] in
|
||||||
@ -888,6 +964,7 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
strongSelf.labelNode.isHidden = !hasServiceMessage
|
strongSelf.labelNode.isHidden = !hasServiceMessage
|
||||||
|
|
||||||
strongSelf.buttonNode.backgroundColor = overlayColor
|
strongSelf.buttonNode.backgroundColor = overlayColor
|
||||||
|
strongSelf.creatorButtonNode.backgroundColor = overlayColor
|
||||||
|
|
||||||
strongSelf.animationNode.updateLayout(size: iconSize)
|
strongSelf.animationNode.updateLayout(size: iconSize)
|
||||||
strongSelf.placeholderNode.frame = animationFrame
|
strongSelf.placeholderNode.frame = animationFrame
|
||||||
@ -906,13 +983,23 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
let _ = buttonTitleApply()
|
let _ = buttonTitleApply()
|
||||||
let _ = ribbonTextApply()
|
let _ = ribbonTextApply()
|
||||||
let _ = moreApply()
|
let _ = moreApply()
|
||||||
|
let _ = creatorButtonTitleApply()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let labelFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((boundingWidth - labelLayout.size.width) / 2.0), y: 2.0), size: labelLayout.size)
|
let labelFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((boundingWidth - labelLayout.size.width) / 2.0), y: 2.0), size: labelLayout.size)
|
||||||
strongSelf.labelNode.frame = labelFrame
|
strongSelf.labelNode.frame = labelFrame
|
||||||
|
|
||||||
let titleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - titleLayout.size.width) / 2.0) , y: mediaBackgroundFrame.minY + 151.0), size: titleLayout.size)
|
let titleFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - titleLayout.size.width) / 2.0) , y: mediaBackgroundFrame.minY + 151.0), size: titleLayout.size)
|
||||||
strongSelf.titleNode.frame = titleFrame
|
strongSelf.titleNode.frame = titleFrame
|
||||||
|
|
||||||
|
let creatorButtonSize = CGSize(width: creatorButtonTitleLayout.size.width + 18.0, height: 18.0)
|
||||||
|
let creatorButtonOriginY = titleFrame.maxY + 4.0
|
||||||
|
strongSelf.creatorButtonTitleNode.frame = CGRect(origin: CGPoint(x: 9.0, y: 1.0), size: creatorButtonTitleLayout.size)
|
||||||
|
|
||||||
|
animation.animator.updateFrame(layer: strongSelf.creatorButtonNode.layer, frame: CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - creatorButtonSize.width) / 2.0), y: creatorButtonOriginY), size: creatorButtonSize), completion: nil)
|
||||||
|
|
||||||
let clippingTextFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - subtitleLayout.size.width) / 2.0), y: titleFrame.maxY + textSpacing), size: CGSize(width: subtitleLayout.size.width, height: clippedTextHeight))
|
let clippingTextFrame = CGRect(origin: CGPoint(x: mediaBackgroundFrame.minX + floorToScreenPixels((mediaBackgroundFrame.width - subtitleLayout.size.width) / 2.0), y: titleFrame.maxY + textSpacing), size: CGSize(width: subtitleLayout.size.width, height: clippedTextHeight))
|
||||||
|
|
||||||
let subtitleFrame = CGRect(origin: .zero, size: subtitleLayout.size)
|
let subtitleFrame = CGRect(origin: .zero, size: subtitleLayout.size)
|
||||||
@ -1355,8 +1442,8 @@ public class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
|
|||||||
return ChatMessageBubbleContentTapAction(content: .none)
|
return ChatMessageBubbleContentTapAction(content: .none)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.buttonNode.frame.contains(point) {
|
if self.buttonNode.frame.contains(point) || self.creatorButtonNode.frame.contains(point) {
|
||||||
return ChatMessageBubbleContentTapAction(content: .ignore)
|
return ChatMessageBubbleContentTapAction(content: .ignore)
|
||||||
} else if self.textClippingNode.frame.contains(point) && !self.isExpanded && !self.moreTextNode.alpha.isZero {
|
} else if self.textClippingNode.frame.contains(point) && !self.isExpanded && !self.moreTextNode.alpha.isZero {
|
||||||
return ChatMessageBubbleContentTapAction(content: .custom({ [weak self] in
|
return ChatMessageBubbleContentTapAction(content: .custom({ [weak self] in
|
||||||
|
|||||||
@ -372,6 +372,19 @@ private func generatePercentageAnimationImages(presentationData: ChatPresentatio
|
|||||||
return images
|
return images
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TodoTrackingButtonNode: HighlightableButtonNode {
|
||||||
|
private var internalHighlighted = false
|
||||||
|
|
||||||
|
public var shouldHighlightAtPoint: (CGPoint) -> Bool = { _ in return true }
|
||||||
|
|
||||||
|
open override func beginTracking(with touch: UITouch, with event: UIEvent?) -> Bool {
|
||||||
|
if self.shouldHighlightAtPoint(touch.location(in: self.view)) {
|
||||||
|
return super.beginTracking(with: touch, with: event)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final class ChatMessageTodoItemNode: ASDisplayNode {
|
private final class ChatMessageTodoItemNode: ASDisplayNode {
|
||||||
private var backgroundWallpaperNode: ChatMessageBubbleBackdrop?
|
private var backgroundWallpaperNode: ChatMessageBubbleBackdrop?
|
||||||
private var backgroundNode: ChatMessageBackground?
|
private var backgroundNode: ChatMessageBackground?
|
||||||
@ -390,7 +403,7 @@ private final class ChatMessageTodoItemNode: ASDisplayNode {
|
|||||||
fileprivate var titleNode: TextNodeWithEntities?
|
fileprivate var titleNode: TextNodeWithEntities?
|
||||||
fileprivate var nameNode: TextNode?
|
fileprivate var nameNode: TextNode?
|
||||||
|
|
||||||
private let buttonNode: HighlightTrackingButtonNode
|
private let buttonNode: TodoTrackingButtonNode
|
||||||
let separatorNode: ASDisplayNode
|
let separatorNode: ASDisplayNode
|
||||||
|
|
||||||
var context: AccountContext?
|
var context: AccountContext?
|
||||||
@ -433,7 +446,7 @@ private final class ChatMessageTodoItemNode: ASDisplayNode {
|
|||||||
self.highlightedBackgroundNode.alpha = 0.0
|
self.highlightedBackgroundNode.alpha = 0.0
|
||||||
self.highlightedBackgroundNode.isUserInteractionEnabled = false
|
self.highlightedBackgroundNode.isUserInteractionEnabled = false
|
||||||
|
|
||||||
self.buttonNode = HighlightTrackingButtonNode()
|
self.buttonNode = TodoTrackingButtonNode()
|
||||||
self.separatorNode = ASDisplayNode()
|
self.separatorNode = ASDisplayNode()
|
||||||
self.separatorNode.isLayerBacked = true
|
self.separatorNode.isLayerBacked = true
|
||||||
|
|
||||||
@ -447,6 +460,15 @@ private final class ChatMessageTodoItemNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.buttonNode)
|
self.addSubnode(self.buttonNode)
|
||||||
|
|
||||||
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
||||||
|
self.buttonNode.shouldHighlightAtPoint = { [weak self] location in
|
||||||
|
guard let self else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if case .none = self.tapActionAtPoint(location, gesture: .tap, isEstimating: true).content {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
self.buttonNode.highligthedChanged = { [weak self] highlighted in
|
self.buttonNode.highligthedChanged = { [weak self] highlighted in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
if highlighted {
|
if highlighted {
|
||||||
|
|||||||
@ -160,6 +160,9 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if case let .unique(gift) = arguments.gift {
|
if case let .unique(gift) = arguments.gift {
|
||||||
|
if let releasedBy = gift.releasedBy {
|
||||||
|
peerIds.append(releasedBy)
|
||||||
|
}
|
||||||
if case let .peerId(peerId) = gift.owner {
|
if case let .peerId(peerId) = gift.owner {
|
||||||
peerIds.append(peerId)
|
peerIds.append(peerId)
|
||||||
}
|
}
|
||||||
@ -192,6 +195,9 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else if case let .generic(gift) = arguments.gift {
|
} else if case let .generic(gift) = arguments.gift {
|
||||||
|
if let releasedBy = gift.releasedBy {
|
||||||
|
peerIds.append(releasedBy)
|
||||||
|
}
|
||||||
if arguments.canUpgrade || arguments.upgradeStars != nil {
|
if arguments.canUpgrade || arguments.upgradeStars != nil {
|
||||||
self.sampleDisposable.add((context.engine.payments.starGiftUpgradePreview(giftId: gift.id)
|
self.sampleDisposable.add((context.engine.payments.starGiftUpgradePreview(giftId: gift.id)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] attributes in
|
|> deliverOnMainQueue).start(next: { [weak self] attributes in
|
||||||
@ -1527,6 +1533,9 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
let buttons = Child(ButtonsComponent.self)
|
let buttons = Child(ButtonsComponent.self)
|
||||||
let animation = Child(GiftCompositionComponent.self)
|
let animation = Child(GiftCompositionComponent.self)
|
||||||
let title = Child(MultilineTextComponent.self)
|
let title = Child(MultilineTextComponent.self)
|
||||||
|
let subtitle = Child(MultilineTextComponent.self)
|
||||||
|
|
||||||
|
let descriptionButton = Child(RoundedRectangle.self)
|
||||||
let description = Child(MultilineTextComponent.self)
|
let description = Child(MultilineTextComponent.self)
|
||||||
|
|
||||||
let transferButton = Child(PlainButtonComponent.self)
|
let transferButton = Child(PlainButtonComponent.self)
|
||||||
@ -1570,6 +1579,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||||
|
|
||||||
var titleString: String
|
var titleString: String
|
||||||
|
var subtitleString: String?
|
||||||
var animationFile: TelegramMediaFile?
|
var animationFile: TelegramMediaFile?
|
||||||
let stars: Int64
|
let stars: Int64
|
||||||
let convertStars: Int64?
|
let convertStars: Int64?
|
||||||
@ -1606,6 +1616,10 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
} else if let arguments = subject.arguments {
|
} else if let arguments = subject.arguments {
|
||||||
switch arguments.gift {
|
switch arguments.gift {
|
||||||
case let .generic(gift):
|
case let .generic(gift):
|
||||||
|
if let releasedBy = gift.releasedBy, let peer = state.peerMap[releasedBy], let addressName = peer.addressName {
|
||||||
|
subtitleString = strings.Gift_View_ReleasedBy("[@\(addressName)]()").string
|
||||||
|
}
|
||||||
|
|
||||||
animationFile = gift.file
|
animationFile = gift.file
|
||||||
stars = gift.price
|
stars = gift.price
|
||||||
text = arguments.text
|
text = arguments.text
|
||||||
@ -2145,9 +2159,15 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var descriptionText: String
|
var descriptionText: String
|
||||||
|
var hasDescriptionButton = false
|
||||||
if let uniqueGift {
|
if let uniqueGift {
|
||||||
titleString = uniqueGift.title
|
titleString = uniqueGift.title
|
||||||
descriptionText = "\(strings.Gift_Unique_Collectible) #\(presentationStringsFormattedNumber(uniqueGift.number, environment.dateTimeFormat.groupingSeparator))"
|
descriptionText = "\(strings.Gift_Unique_Collectible) #\(presentationStringsFormattedNumber(uniqueGift.number, environment.dateTimeFormat.groupingSeparator))"
|
||||||
|
|
||||||
|
if let releasedBy = uniqueGift.releasedBy, let peer = state.peerMap[releasedBy], let addressName = peer.addressName {
|
||||||
|
descriptionText = strings.Gift_Unique_CollectibleBy("#\(presentationStringsFormattedNumber(uniqueGift.number, environment.dateTimeFormat.groupingSeparator))", "[@\(addressName)]()").string
|
||||||
|
hasDescriptionButton = true
|
||||||
|
}
|
||||||
} else if soldOut {
|
} else if soldOut {
|
||||||
descriptionText = strings.Gift_View_UnavailableDescription
|
descriptionText = strings.Gift_View_UnavailableDescription
|
||||||
} else if upgraded {
|
} else if upgraded {
|
||||||
@ -2197,7 +2217,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
component: MultilineTextComponent(
|
component: MultilineTextComponent(
|
||||||
text: .plain(NSAttributedString(
|
text: .plain(NSAttributedString(
|
||||||
string: titleString,
|
string: titleString,
|
||||||
font: uniqueGift != nil ? Font.bold(20.0) : Font.bold(25.0),
|
font: Font.bold(20.0),
|
||||||
textColor: uniqueGift != nil ? .white : theme.actionSheet.primaryTextColor,
|
textColor: uniqueGift != nil ? .white : theme.actionSheet.primaryTextColor,
|
||||||
paragraphAlignment: .center
|
paragraphAlignment: .center
|
||||||
)),
|
)),
|
||||||
@ -2208,13 +2228,41 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
transition: .immediate
|
transition: .immediate
|
||||||
)
|
)
|
||||||
context.add(title
|
context.add(title
|
||||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: uniqueGift != nil ? 190.0 : 177.0))
|
.position(CGPoint(x: context.availableSize.width / 2.0, y: uniqueGift != nil ? 190.0 : 173.0))
|
||||||
.appear(.default(alpha: true))
|
.appear(.default(alpha: true))
|
||||||
.disappear(.default(alpha: true))
|
.disappear(.default(alpha: true))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var descriptionOffset: CGFloat = 0.0
|
||||||
|
if let subtitleString {
|
||||||
|
let subtitle = subtitle.update(
|
||||||
|
component: MultilineTextComponent(
|
||||||
|
text: .plain(NSAttributedString(
|
||||||
|
string: subtitleString,
|
||||||
|
font: Font.regular(13.0),
|
||||||
|
textColor: theme.actionSheet.secondaryTextColor,
|
||||||
|
paragraphAlignment: .center
|
||||||
|
)),
|
||||||
|
horizontalAlignment: .center,
|
||||||
|
maximumNumberOfLines: 1
|
||||||
|
),
|
||||||
|
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - 60.0, height: CGFloat.greatestFiniteMagnitude),
|
||||||
|
transition: .immediate
|
||||||
|
)
|
||||||
|
context.add(subtitle
|
||||||
|
.position(CGPoint(x: context.availableSize.width / 2.0, y: uniqueGift != nil ? 210.0 : 196.0))
|
||||||
|
.appear(.default(alpha: true))
|
||||||
|
.disappear(.default(alpha: true))
|
||||||
|
)
|
||||||
|
descriptionOffset += subtitle.size.height
|
||||||
|
}
|
||||||
|
|
||||||
if !descriptionText.isEmpty {
|
if !descriptionText.isEmpty {
|
||||||
let linkColor = theme.actionSheet.controlAccentColor
|
var linkColor = theme.actionSheet.controlAccentColor
|
||||||
|
if hasDescriptionButton {
|
||||||
|
linkColor = UIColor.white
|
||||||
|
}
|
||||||
|
|
||||||
if state.cachedSmallStarImage == nil || state.cachedSmallStarImage?.1 !== environment.theme {
|
if state.cachedSmallStarImage == nil || state.cachedSmallStarImage?.1 !== environment.theme {
|
||||||
state.cachedSmallStarImage = (generateTintedImage(image: UIImage(bundleImageName: "Premium/Stars/ButtonStar"), color: .white)!, theme)
|
state.cachedSmallStarImage = (generateTintedImage(image: UIImage(bundleImageName: "Premium/Stars/ButtonStar"), color: .white)!, theme)
|
||||||
}
|
}
|
||||||
@ -2226,7 +2274,11 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
let textColor: UIColor
|
let textColor: UIColor
|
||||||
if let _ = uniqueGift {
|
if let _ = uniqueGift {
|
||||||
textFont = Font.regular(13.0)
|
textFont = Font.regular(13.0)
|
||||||
textColor = vibrantColor
|
if hasDescriptionButton {
|
||||||
|
textColor = vibrantColor.mixedWith(UIColor.white, alpha: 0.5)
|
||||||
|
} else {
|
||||||
|
textColor = vibrantColor
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
textFont = soldOut ? Font.medium(15.0) : Font.regular(15.0)
|
textFont = soldOut ? Font.medium(15.0) : Font.regular(15.0)
|
||||||
textColor = soldOut ? theme.list.itemDestructiveColor : theme.list.itemPrimaryTextColor
|
textColor = soldOut ? theme.list.itemDestructiveColor : theme.list.itemPrimaryTextColor
|
||||||
@ -2245,6 +2297,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
if let range = attributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 {
|
if let range = attributedString.string.range(of: ">"), let chevronImage = state.cachedChevronImage?.0 {
|
||||||
attributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: attributedString.string))
|
attributedString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: attributedString.string))
|
||||||
}
|
}
|
||||||
|
|
||||||
let description = description.update(
|
let description = description.update(
|
||||||
component: MultilineTextComponent(
|
component: MultilineTextComponent(
|
||||||
text: .plain(attributedString),
|
text: .plain(attributedString),
|
||||||
@ -2269,12 +2322,29 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||||||
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - 50.0, height: CGFloat.greatestFiniteMagnitude),
|
availableSize: CGSize(width: context.availableSize.width - sideInset * 2.0 - 50.0, height: CGFloat.greatestFiniteMagnitude),
|
||||||
transition: .immediate
|
transition: .immediate
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if hasDescriptionButton {
|
||||||
|
let descriptionButton = descriptionButton.update(
|
||||||
|
component: RoundedRectangle(color: UIColor.white.withAlphaComponent(0.15), cornerRadius: 9.5),
|
||||||
|
environment: {},
|
||||||
|
availableSize: CGSize(width: description.size.width + 18.0, height: 19.0),
|
||||||
|
transition: .immediate
|
||||||
|
)
|
||||||
|
context.add(descriptionButton
|
||||||
|
.position(CGPoint(x: context.availableSize.width / 2.0, y: 207.0 + descriptionOffset + description.size.height / 2.0 - UIScreenPixel))
|
||||||
|
.appear(.default(alpha: true))
|
||||||
|
.disappear(.default(alpha: true))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
context.add(description
|
context.add(description
|
||||||
.position(CGPoint(x: context.availableSize.width / 2.0, y: 207.0 + description.size.height / 2.0))
|
.position(CGPoint(x: context.availableSize.width / 2.0, y: 207.0 + descriptionOffset + description.size.height / 2.0))
|
||||||
.appear(.default(alpha: true))
|
.appear(.default(alpha: true))
|
||||||
.disappear(.default(alpha: true))
|
.disappear(.default(alpha: true))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
originY += descriptionOffset
|
||||||
|
|
||||||
if uniqueGift != nil {
|
if uniqueGift != nil {
|
||||||
originY += 16.0
|
originY += 16.0
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -460,7 +460,8 @@ final class UserAppearanceScreenComponent: Component {
|
|||||||
],
|
],
|
||||||
availability: StarGift.UniqueGift.Availability(issued: 0, total: 0),
|
availability: StarGift.UniqueGift.Availability(issued: 0, total: 0),
|
||||||
giftAddress: nil,
|
giftAddress: nil,
|
||||||
resellStars: nil
|
resellStars: nil,
|
||||||
|
releasedBy: nil
|
||||||
)
|
)
|
||||||
signal = component.context.engine.accountData.setStarGiftStatus(starGift: gift, expirationDate: emojiStatus.expirationDate)
|
signal = component.context.engine.accountData.setStarGiftStatus(starGift: gift, expirationDate: emojiStatus.expirationDate)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -5061,6 +5061,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
}
|
}
|
||||||
self.dismissAllTooltips()
|
self.dismissAllTooltips()
|
||||||
|
|
||||||
|
if let message = self.chatDisplayNode.historyNode.messageInCurrentHistoryView(messageId), let _ = message.forwardInfo {
|
||||||
|
let controller = UndoOverlayController(
|
||||||
|
presentationData: self.presentationData,
|
||||||
|
content: .universalImage(image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Stickers/Lock"), color: .white)!, size: nil, title: nil, text: self.presentationData.strings.Chat_Todo_CompletionLimitedForward, customUndoText: nil, timeout: nil),
|
||||||
|
action: { _ in
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.present(controller, in: .current)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
guard self.presentationInterfaceState.subject != .scheduledMessages else {
|
guard self.presentationInterfaceState.subject != .scheduledMessages else {
|
||||||
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.ScheduledMessages_TodoUnavailable, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
self.present(textAlertController(context: self.context, updatedPresentationData: self.updatedPresentationData, title: nil, text: self.presentationData.strings.ScheduledMessages_TodoUnavailable, actions: [TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||||
return
|
return
|
||||||
|
|||||||
@ -2117,6 +2117,20 @@ extension ChatControllerImpl {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
guard self.context.isPremium else {
|
||||||
|
let context = self.context
|
||||||
|
var replaceImpl: ((ViewController) -> Void)?
|
||||||
|
let demoController = context.sharedContext.makePremiumDemoController(context: context, subject: .todo, forceDark: false, action: {
|
||||||
|
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .todo, forceDark: false, dismissed: nil)
|
||||||
|
replaceImpl?(controller)
|
||||||
|
}, dismissed: nil)
|
||||||
|
replaceImpl = { [weak demoController] c in
|
||||||
|
demoController?.replace(with: c)
|
||||||
|
}
|
||||||
|
self.push(demoController)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
let canEdit = canEditMessage(context: self.context, limitsConfiguration: self.context.currentLimitsConfiguration.with { EngineConfiguration.Limits($0) }, message: message)
|
let canEdit = canEditMessage(context: self.context, limitsConfiguration: self.context.currentLimitsConfiguration.with { EngineConfiguration.Limits($0) }, message: message)
|
||||||
|
|
||||||
let controller = ComposeTodoScreen(
|
let controller = ComposeTodoScreen(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user