mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-30 19:58:39 +00:00
Stories
This commit is contained in:
parent
fcdfd8e00f
commit
c880397eca
@ -1338,9 +1338,9 @@ public final class Transaction {
|
||||
self.postbox!.setStoryItems(peerId: peerId, items: items)
|
||||
}
|
||||
|
||||
public func setStoryItemsInexactMaxId(peerId: PeerId, id: Int32) {
|
||||
public func setStoryItemsInexactMaxId(peerId: PeerId, id: Int32, hasLiveItems: Bool) {
|
||||
assert(!self.disposed)
|
||||
self.postbox!.setStoryItemsInexactMaxId(peerId: peerId, id: id)
|
||||
self.postbox!.setStoryItemsInexactMaxId(peerId: peerId, id: id, hasLiveItems: hasLiveItems)
|
||||
}
|
||||
|
||||
public func clearStoryItemsInexactMaxId(peerId: PeerId) {
|
||||
@ -2451,10 +2451,10 @@ final class PostboxImpl {
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func setStoryItemsInexactMaxId(peerId: PeerId, id: Int32) {
|
||||
fileprivate func setStoryItemsInexactMaxId(peerId: PeerId, id: Int32, hasLiveItems: Bool) {
|
||||
if let value = self.storyTopItemsTable.get(peerId: peerId), value.id >= id {
|
||||
} else {
|
||||
self.storyTopItemsTable.set(peerId: peerId, entry: StoryTopItemsTable.Entry(id: id, isExact: false), events: &self.currentStoryTopItemEvents)
|
||||
self.storyTopItemsTable.set(peerId: peerId, entry: StoryTopItemsTable.Entry(id: id, isExact: false, hasLiveItems: hasLiveItems), events: &self.currentStoryTopItemEvents)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -48,6 +48,7 @@ final class StoryTopItemsTable: Table {
|
||||
struct Entry {
|
||||
var id: Int32
|
||||
var isExact: Bool
|
||||
var hasLiveItems: Bool
|
||||
}
|
||||
|
||||
enum Event {
|
||||
@ -78,10 +79,12 @@ final class StoryTopItemsTable: Table {
|
||||
}
|
||||
var maxId: Int32 = 0
|
||||
buffer.read(&maxId, offset: 0, length: 4)
|
||||
var isExact: Int8 = 0
|
||||
buffer.read(&isExact, offset: 0, length: 1)
|
||||
var flags: Int8 = 0
|
||||
buffer.read(&flags, offset: 0, length: 1)
|
||||
let isExact = (flags & (1 << 0)) != 0
|
||||
let hasLiveItems = (flags & (1 << 1)) != 0
|
||||
|
||||
return Entry(id: maxId, isExact: isExact != 0)
|
||||
return Entry(id: maxId, isExact: isExact, hasLiveItems: hasLiveItems)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
@ -95,8 +98,14 @@ final class StoryTopItemsTable: Table {
|
||||
buffer.write(&version, length: 1)
|
||||
var maxId = entry.id
|
||||
buffer.write(&maxId, length: 4)
|
||||
var isExact: Int8 = entry.isExact ? 1 : 0
|
||||
buffer.write(&isExact, length: 1)
|
||||
var flags: Int8 = 0
|
||||
if entry.isExact {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
if entry.hasLiveItems {
|
||||
flags |= 1 << 1
|
||||
}
|
||||
buffer.write(&flags, length: 1)
|
||||
|
||||
self.valueBox.set(self.table, key: self.key(Key(peerId: peerId)), value: buffer.readBufferNoCopy())
|
||||
} else {
|
||||
@ -382,6 +391,8 @@ final class StoryItemsTable: Table {
|
||||
self.valueBox.remove(self.table, key: key, secure: true)
|
||||
}
|
||||
|
||||
var hasLiveItems = false
|
||||
|
||||
let buffer = WriteBuffer()
|
||||
for entry in entries {
|
||||
buffer.reset()
|
||||
@ -401,6 +412,7 @@ final class StoryItemsTable: Table {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
if entry.isLiveStream {
|
||||
hasLiveItems = true
|
||||
flags |= (1 << 1)
|
||||
}
|
||||
buffer.write(&flags, length: 1)
|
||||
@ -410,7 +422,7 @@ final class StoryItemsTable: Table {
|
||||
|
||||
events.append(.replace(peerId: peerId))
|
||||
|
||||
topItemTable.set(peerId: peerId, entry: StoryTopItemsTable.Entry(id: entries.last?.id ?? 0, isExact: true), events: &topItemEvents)
|
||||
topItemTable.set(peerId: peerId, entry: StoryTopItemsTable.Entry(id: entries.last?.id ?? 0, isExact: true, hasLiveItems: hasLiveItems), events: &topItemEvents)
|
||||
}
|
||||
|
||||
override func clearMemoryCache() {
|
||||
|
||||
@ -196,7 +196,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-531931925] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsMentions($0) }
|
||||
dict[-566281095] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsRecent($0) }
|
||||
dict[106343499] = { return Api.ChannelParticipantsFilter.parse_channelParticipantsSearch($0) }
|
||||
dict[-26717355] = { return Api.Chat.parse_channel($0) }
|
||||
dict[473084188] = { return Api.Chat.parse_channel($0) }
|
||||
dict[399807445] = { return Api.Chat.parse_channelForbidden($0) }
|
||||
dict[1103884886] = { return Api.Chat.parse_chat($0) }
|
||||
dict[693512293] = { return Api.Chat.parse_chatEmpty($0) }
|
||||
@ -857,6 +857,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-1140172836] = { return Api.RecentMeUrl.parse_recentMeUrlStickerSet($0) }
|
||||
dict[1189204285] = { return Api.RecentMeUrl.parse_recentMeUrlUnknown($0) }
|
||||
dict[-1188296222] = { return Api.RecentMeUrl.parse_recentMeUrlUser($0) }
|
||||
dict[1897752877] = { return Api.RecentStory.parse_recentStory($0) }
|
||||
dict[1218642516] = { return Api.ReplyMarkup.parse_replyInlineMarkup($0) }
|
||||
dict[-2035021048] = { return Api.ReplyMarkup.parse_replyKeyboardForceReply($0) }
|
||||
dict[-1606526075] = { return Api.ReplyMarkup.parse_replyKeyboardHide($0) }
|
||||
@ -1208,7 +1209,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-1886646706] = { return Api.UrlAuthResult.parse_urlAuthResultAccepted($0) }
|
||||
dict[-1445536993] = { return Api.UrlAuthResult.parse_urlAuthResultDefault($0) }
|
||||
dict[-1831650802] = { return Api.UrlAuthResult.parse_urlAuthResultRequest($0) }
|
||||
dict[34280482] = { return Api.User.parse_user($0) }
|
||||
dict[829899656] = { return Api.User.parse_user($0) }
|
||||
dict[-742634630] = { return Api.User.parse_userEmpty($0) }
|
||||
dict[-1607745218] = { return Api.UserFull.parse_userFull($0) }
|
||||
dict[-2100168954] = { return Api.UserProfilePhoto.parse_userProfilePhoto($0) }
|
||||
@ -2126,6 +2127,8 @@ public extension Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.RecentMeUrl:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.RecentStory:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.ReplyMarkup:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.ReportReason:
|
||||
|
||||
@ -174,6 +174,46 @@ public extension Api {
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum RecentStory: TypeConstructorDescription {
|
||||
case recentStory(flags: Int32, maxId: Int32?)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .recentStory(let flags, let maxId):
|
||||
if boxed {
|
||||
buffer.appendInt32(1897752877)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 1) != 0 {serializeInt32(maxId!, buffer: buffer, boxed: false)}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .recentStory(let flags, let maxId):
|
||||
return ("recentStory", [("flags", flags as Any), ("maxId", maxId as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_recentStory(_ reader: BufferReader) -> RecentStory? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
if Int(_1!) & Int(1 << 1) != 0 {_2 = reader.readInt32() }
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = (Int(_1!) & Int(1 << 1) == 0) || _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.RecentStory.recentStory(flags: _1!, maxId: _2)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public extension Api {
|
||||
enum ReplyMarkup: TypeConstructorDescription {
|
||||
case replyInlineMarkup(rows: [Api.KeyboardButtonRow])
|
||||
|
||||
@ -452,14 +452,14 @@ public extension Api {
|
||||
}
|
||||
public extension Api {
|
||||
enum User: TypeConstructorDescription {
|
||||
case user(flags: Int32, flags2: Int32, id: Int64, accessHash: Int64?, firstName: String?, lastName: String?, username: String?, phone: String?, photo: Api.UserProfilePhoto?, status: Api.UserStatus?, botInfoVersion: Int32?, restrictionReason: [Api.RestrictionReason]?, botInlinePlaceholder: String?, langCode: String?, emojiStatus: Api.EmojiStatus?, usernames: [Api.Username]?, storiesMaxId: Int32?, color: Api.PeerColor?, profileColor: Api.PeerColor?, botActiveUsers: Int32?, botVerificationIcon: Int64?, sendPaidMessagesStars: Int64?)
|
||||
case user(flags: Int32, flags2: Int32, id: Int64, accessHash: Int64?, firstName: String?, lastName: String?, username: String?, phone: String?, photo: Api.UserProfilePhoto?, status: Api.UserStatus?, botInfoVersion: Int32?, restrictionReason: [Api.RestrictionReason]?, botInlinePlaceholder: String?, langCode: String?, emojiStatus: Api.EmojiStatus?, usernames: [Api.Username]?, storiesMaxId: Api.RecentStory?, color: Api.PeerColor?, profileColor: Api.PeerColor?, botActiveUsers: Int32?, botVerificationIcon: Int64?, sendPaidMessagesStars: Int64?)
|
||||
case userEmpty(id: Int64)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .user(let flags, let flags2, let id, let accessHash, let firstName, let lastName, let username, let phone, let photo, let status, let botInfoVersion, let restrictionReason, let botInlinePlaceholder, let langCode, let emojiStatus, let usernames, let storiesMaxId, let color, let profileColor, let botActiveUsers, let botVerificationIcon, let sendPaidMessagesStars):
|
||||
if boxed {
|
||||
buffer.appendInt32(34280482)
|
||||
buffer.appendInt32(829899656)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(flags2, buffer: buffer, boxed: false)
|
||||
@ -485,7 +485,7 @@ public extension Api {
|
||||
for item in usernames! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags2) & Int(1 << 5) != 0 {serializeInt32(storiesMaxId!, buffer: buffer, boxed: false)}
|
||||
if Int(flags2) & Int(1 << 5) != 0 {storiesMaxId!.serialize(buffer, true)}
|
||||
if Int(flags2) & Int(1 << 8) != 0 {color!.serialize(buffer, true)}
|
||||
if Int(flags2) & Int(1 << 9) != 0 {profileColor!.serialize(buffer, true)}
|
||||
if Int(flags2) & Int(1 << 12) != 0 {serializeInt32(botActiveUsers!, buffer: buffer, boxed: false)}
|
||||
@ -553,8 +553,10 @@ public extension Api {
|
||||
if Int(_2!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||
_16 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Username.self)
|
||||
} }
|
||||
var _17: Int32?
|
||||
if Int(_2!) & Int(1 << 5) != 0 {_17 = reader.readInt32() }
|
||||
var _17: Api.RecentStory?
|
||||
if Int(_2!) & Int(1 << 5) != 0 {if let signature = reader.readInt32() {
|
||||
_17 = Api.parse(reader, signature: signature) as? Api.RecentStory
|
||||
} }
|
||||
var _18: Api.PeerColor?
|
||||
if Int(_2!) & Int(1 << 8) != 0 {if let signature = reader.readInt32() {
|
||||
_18 = Api.parse(reader, signature: signature) as? Api.PeerColor
|
||||
|
||||
@ -11816,19 +11816,19 @@ public extension Api.functions.stories {
|
||||
}
|
||||
}
|
||||
public extension Api.functions.stories {
|
||||
static func getPeerMaxIDs(id: [Api.InputPeer]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Int32]>) {
|
||||
static func getPeerMaxIDs(id: [Api.InputPeer]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.RecentStory]>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(1398375363)
|
||||
buffer.appendInt32(2018087280)
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(id.count))
|
||||
for item in id {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
return (FunctionDescription(name: "stories.getPeerMaxIDs", parameters: [("id", String(describing: id))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> [Int32]? in
|
||||
return (FunctionDescription(name: "stories.getPeerMaxIDs", parameters: [("id", String(describing: id))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> [Api.RecentStory]? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: [Int32]?
|
||||
var result: [Api.RecentStory]?
|
||||
if let _ = reader.readInt32() {
|
||||
result = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
|
||||
result = Api.parseVector(reader, elementSignature: 0, elementType: Api.RecentStory.self)
|
||||
}
|
||||
return result
|
||||
})
|
||||
|
||||
@ -534,7 +534,7 @@ public extension Api {
|
||||
}
|
||||
public extension Api {
|
||||
indirect enum Chat: TypeConstructorDescription {
|
||||
case channel(flags: Int32, flags2: Int32, id: Int64, accessHash: Int64?, title: String, username: String?, photo: Api.ChatPhoto, date: Int32, restrictionReason: [Api.RestrictionReason]?, adminRights: Api.ChatAdminRights?, bannedRights: Api.ChatBannedRights?, defaultBannedRights: Api.ChatBannedRights?, participantsCount: Int32?, usernames: [Api.Username]?, storiesMaxId: Int32?, color: Api.PeerColor?, profileColor: Api.PeerColor?, emojiStatus: Api.EmojiStatus?, level: Int32?, subscriptionUntilDate: Int32?, botVerificationIcon: Int64?, sendPaidMessagesStars: Int64?, linkedMonoforumId: Int64?)
|
||||
case channel(flags: Int32, flags2: Int32, id: Int64, accessHash: Int64?, title: String, username: String?, photo: Api.ChatPhoto, date: Int32, restrictionReason: [Api.RestrictionReason]?, adminRights: Api.ChatAdminRights?, bannedRights: Api.ChatBannedRights?, defaultBannedRights: Api.ChatBannedRights?, participantsCount: Int32?, usernames: [Api.Username]?, storiesMaxId: Api.RecentStory?, color: Api.PeerColor?, profileColor: Api.PeerColor?, emojiStatus: Api.EmojiStatus?, level: Int32?, subscriptionUntilDate: Int32?, botVerificationIcon: Int64?, sendPaidMessagesStars: Int64?, linkedMonoforumId: Int64?)
|
||||
case channelForbidden(flags: Int32, id: Int64, accessHash: Int64, title: String, untilDate: Int32?)
|
||||
case chat(flags: Int32, id: Int64, title: String, photo: Api.ChatPhoto, participantsCount: Int32, date: Int32, version: Int32, migratedTo: Api.InputChannel?, adminRights: Api.ChatAdminRights?, defaultBannedRights: Api.ChatBannedRights?)
|
||||
case chatEmpty(id: Int64)
|
||||
@ -544,7 +544,7 @@ public extension Api {
|
||||
switch self {
|
||||
case .channel(let flags, let flags2, let id, let accessHash, let title, let username, let photo, let date, let restrictionReason, let adminRights, let bannedRights, let defaultBannedRights, let participantsCount, let usernames, let storiesMaxId, let color, let profileColor, let emojiStatus, let level, let subscriptionUntilDate, let botVerificationIcon, let sendPaidMessagesStars, let linkedMonoforumId):
|
||||
if boxed {
|
||||
buffer.appendInt32(-26717355)
|
||||
buffer.appendInt32(473084188)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(flags2, buffer: buffer, boxed: false)
|
||||
@ -568,7 +568,7 @@ public extension Api {
|
||||
for item in usernames! {
|
||||
item.serialize(buffer, true)
|
||||
}}
|
||||
if Int(flags2) & Int(1 << 4) != 0 {serializeInt32(storiesMaxId!, buffer: buffer, boxed: false)}
|
||||
if Int(flags2) & Int(1 << 4) != 0 {storiesMaxId!.serialize(buffer, true)}
|
||||
if Int(flags2) & Int(1 << 7) != 0 {color!.serialize(buffer, true)}
|
||||
if Int(flags2) & Int(1 << 8) != 0 {profileColor!.serialize(buffer, true)}
|
||||
if Int(flags2) & Int(1 << 9) != 0 {emojiStatus!.serialize(buffer, true)}
|
||||
@ -675,8 +675,10 @@ public extension Api {
|
||||
if Int(_2!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
|
||||
_14 = Api.parseVector(reader, elementSignature: 0, elementType: Api.Username.self)
|
||||
} }
|
||||
var _15: Int32?
|
||||
if Int(_2!) & Int(1 << 4) != 0 {_15 = reader.readInt32() }
|
||||
var _15: Api.RecentStory?
|
||||
if Int(_2!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
|
||||
_15 = Api.parse(reader, signature: signature) as? Api.RecentStory
|
||||
} }
|
||||
var _16: Api.PeerColor?
|
||||
if Int(_2!) & Int(1 << 7) != 0 {if let signature = reader.readInt32() {
|
||||
_16 = Api.parse(reader, signature: signature) as? Api.PeerColor
|
||||
|
||||
@ -1431,7 +1431,7 @@ public final class AccountViewTracker {
|
||||
}
|
||||
startIndex += batchCount
|
||||
requests.append(account.network.request(Api.functions.stories.getPeerMaxIDs(id: slice.map(\.1)))
|
||||
|> `catch` { _ -> Signal<[Int32], NoError> in
|
||||
|> `catch` { _ -> Signal<[Api.RecentStory], NoError> in
|
||||
return .single([])
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Never, NoError> in
|
||||
@ -1439,10 +1439,13 @@ public final class AccountViewTracker {
|
||||
for i in 0 ..< result.count {
|
||||
if i < slice.count {
|
||||
let value = result[i]
|
||||
if value <= 0 {
|
||||
transaction.clearStoryItemsInexactMaxId(peerId: slice[i].0)
|
||||
} else {
|
||||
transaction.setStoryItemsInexactMaxId(peerId: slice[i].0, id: value)
|
||||
switch value {
|
||||
case let .recentStory(flags, maxId):
|
||||
if let maxId {
|
||||
transaction.setStoryItemsInexactMaxId(peerId: slice[i].0, id: maxId, hasLiveItems: (flags & (1 << 0)) != 0)
|
||||
} else {
|
||||
transaction.clearStoryItemsInexactMaxId(peerId: slice[i].0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3703,6 +3703,7 @@ public final class GroupCallMessagesContext {
|
||||
}
|
||||
|
||||
public let id: Id
|
||||
public let stableId: Int
|
||||
public let author: EnginePeer?
|
||||
public let text: String
|
||||
public let entities: [MessageTextEntity]
|
||||
@ -3710,8 +3711,9 @@ public final class GroupCallMessagesContext {
|
||||
public let lifetime: Int32
|
||||
public let paidStars: Int64?
|
||||
|
||||
public init(id: Id, author: EnginePeer?, text: String, entities: [MessageTextEntity], date: Int32, lifetime: Int32, paidStars: Int64?) {
|
||||
public init(id: Id, stableId: Int, author: EnginePeer?, text: String, entities: [MessageTextEntity], date: Int32, lifetime: Int32, paidStars: Int64?) {
|
||||
self.id = id
|
||||
self.stableId = stableId
|
||||
self.author = author
|
||||
self.text = text
|
||||
self.entities = entities
|
||||
@ -3723,6 +3725,7 @@ public final class GroupCallMessagesContext {
|
||||
public func withId(_ id: Id) -> Message {
|
||||
return Message(
|
||||
id: id,
|
||||
stableId: self.stableId,
|
||||
author: self.author,
|
||||
text: self.text,
|
||||
entities: self.entities,
|
||||
@ -3733,11 +3736,14 @@ public final class GroupCallMessagesContext {
|
||||
}
|
||||
|
||||
public static func ==(lhs: Message, rhs: Message) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.id != rhs.id {
|
||||
return false
|
||||
}
|
||||
if lhs === rhs {
|
||||
return true
|
||||
if lhs.stableId != rhs.stableId {
|
||||
return false
|
||||
}
|
||||
if lhs.author != rhs.author {
|
||||
return false
|
||||
@ -3837,6 +3843,7 @@ public final class GroupCallMessagesContext {
|
||||
let sendMessageDisposables = DisposableSet()
|
||||
|
||||
var processedIds = Set<Int64>()
|
||||
var nextStableId: Int = 0
|
||||
|
||||
private var messageLifeTimer: SwiftSignalKit.Timer?
|
||||
|
||||
@ -3881,6 +3888,11 @@ public final class GroupCallMessagesContext {
|
||||
if !addedMessages.isEmpty || !addedOpaqueMessages.isEmpty {
|
||||
let messageLifetime = self.messageLifetime
|
||||
let isLiveStream = self.isLiveStream
|
||||
let allocatedStableIds = (0 ..< (addedOpaqueMessages.count + addedMessages.count)).map { _ in
|
||||
let value = self.nextStableId
|
||||
self.nextStableId += 1
|
||||
return value
|
||||
}
|
||||
|
||||
let _ = (self.account.postbox.transaction { transaction -> [Message] in
|
||||
var messages: [Message] = []
|
||||
@ -3907,8 +3919,13 @@ public final class GroupCallMessagesContext {
|
||||
guard let (randomId, text, entities) = deserializeGroupCallMessage(data: decryptedMessage) else {
|
||||
continue
|
||||
}
|
||||
if allocatedStableIds.count <= messages.count {
|
||||
assertionFailure()
|
||||
break
|
||||
}
|
||||
messages.append(Message(
|
||||
id: Message.Id(space: .remote, id: randomId),
|
||||
stableId: allocatedStableIds[messages.count],
|
||||
author: transaction.getPeer(addedOpaqueMessage.authorId).flatMap(EnginePeer.init),
|
||||
text: text,
|
||||
entities: entities,
|
||||
@ -3930,16 +3947,21 @@ public final class GroupCallMessagesContext {
|
||||
lifetime = self.messageLifetime
|
||||
}
|
||||
|
||||
let message = Message(
|
||||
if allocatedStableIds.count <= messages.count {
|
||||
assertionFailure()
|
||||
break
|
||||
}
|
||||
|
||||
messages.append(Message(
|
||||
id: Message.Id(space: .remote, id: Int64(addedMessage.messageId)),
|
||||
stableId: allocatedStableIds[messages.count],
|
||||
author: transaction.getPeer(addedMessage.authorId).flatMap(EnginePeer.init),
|
||||
text: addedMessage.text,
|
||||
entities: addedMessage.entities,
|
||||
date: addedMessage.timestamp,
|
||||
lifetime: lifetime,
|
||||
paidStars: addedMessage.paidMessageStars
|
||||
)
|
||||
messages.append(message)
|
||||
))
|
||||
}
|
||||
}
|
||||
return messages
|
||||
@ -3973,6 +3995,12 @@ public final class GroupCallMessagesContext {
|
||||
}
|
||||
}
|
||||
}
|
||||
state.messages.sort(by: { lhs, rhs in
|
||||
if lhs.date != rhs.date {
|
||||
return lhs.date < rhs.date
|
||||
}
|
||||
return lhs.stableId < rhs.stableId
|
||||
})
|
||||
self.state = state
|
||||
|
||||
self.didInitializeTopStars = true
|
||||
@ -4203,8 +4231,11 @@ public final class GroupCallMessagesContext {
|
||||
}
|
||||
|
||||
var state = self.state
|
||||
let stableId = self.nextStableId
|
||||
self.nextStableId += 1
|
||||
let message = Message(
|
||||
id: Message.Id(space: .local, id: randomId),
|
||||
stableId: stableId,
|
||||
author: fromPeer.flatMap(EnginePeer.init),
|
||||
text: text,
|
||||
entities: entities,
|
||||
@ -4403,6 +4434,7 @@ public final class GroupCallMessagesContext {
|
||||
state.messages.remove(at: index)
|
||||
state.messages.append(Message(
|
||||
id: message.id,
|
||||
stableId: message.stableId,
|
||||
author: message.author,
|
||||
text: message.text,
|
||||
entities: message.entities,
|
||||
@ -4411,8 +4443,11 @@ public final class GroupCallMessagesContext {
|
||||
paidStars: totalAmount
|
||||
))
|
||||
} else {
|
||||
let stableId = self.nextStableId
|
||||
self.nextStableId += 1
|
||||
state.messages.append(Message(
|
||||
id: Message.Id(space: .local, id: pendingSendStarsValue.messageId),
|
||||
stableId: stableId,
|
||||
author: fromPeer.flatMap(EnginePeer.init),
|
||||
text: "",
|
||||
entities: [],
|
||||
@ -4426,6 +4461,7 @@ public final class GroupCallMessagesContext {
|
||||
state.pinnedMessages.remove(at: index)
|
||||
state.pinnedMessages.append(Message(
|
||||
id: message.id,
|
||||
stableId: message.stableId,
|
||||
author: message.author,
|
||||
text: message.text,
|
||||
entities: message.entities,
|
||||
@ -4434,8 +4470,11 @@ public final class GroupCallMessagesContext {
|
||||
paidStars: totalAmount
|
||||
))
|
||||
} else {
|
||||
let stableId = self.nextStableId
|
||||
self.nextStableId += 1
|
||||
state.pinnedMessages.append(Message(
|
||||
id: Message.Id(space: .local, id: pendingSendStarsValue.messageId),
|
||||
stableId: stableId,
|
||||
author: fromPeer.flatMap(EnginePeer.init),
|
||||
text: "",
|
||||
entities: [],
|
||||
|
||||
@ -55,8 +55,17 @@ func updatePeers(transaction: Transaction, accountPeerId: PeerId, peers: Accumul
|
||||
let isMin = (flags & (1 << 20)) != 0
|
||||
let storiesUnavailable = (flags2 & (1 << 4)) != 0
|
||||
|
||||
if let storiesMaxId = storiesMaxId {
|
||||
transaction.setStoryItemsInexactMaxId(peerId: user.peerId, id: storiesMaxId)
|
||||
if let storiesMaxId {
|
||||
switch storiesMaxId {
|
||||
case let .recentStory(flags, maxId):
|
||||
if let maxId {
|
||||
transaction.setStoryItemsInexactMaxId(peerId: user.peerId, id: maxId, hasLiveItems: (flags & (1 << 0)) != 0)
|
||||
} else {
|
||||
if !isMin && storiesUnavailable {
|
||||
transaction.clearStoryItemsInexactMaxId(peerId: user.peerId)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if !isMin && storiesUnavailable {
|
||||
transaction.clearStoryItemsInexactMaxId(peerId: user.peerId)
|
||||
}
|
||||
@ -76,8 +85,17 @@ func updatePeers(transaction: Transaction, accountPeerId: PeerId, peers: Accumul
|
||||
let isMin = (flags & (1 << 12)) != 0
|
||||
let storiesUnavailable = (flags2 & (1 << 3)) != 0
|
||||
|
||||
if let storiesMaxId = storiesMaxId {
|
||||
transaction.setStoryItemsInexactMaxId(peerId: chat.peerId, id: storiesMaxId)
|
||||
if let storiesMaxId {
|
||||
switch storiesMaxId {
|
||||
case let .recentStory(flags, maxId):
|
||||
if let maxId {
|
||||
transaction.setStoryItemsInexactMaxId(peerId: chat.peerId, id: maxId, hasLiveItems: (flags & (1 << 0)) != 0)
|
||||
} else {
|
||||
if !isMin && storiesUnavailable {
|
||||
transaction.clearStoryItemsInexactMaxId(peerId: chat.peerId)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if !isMin && storiesUnavailable {
|
||||
transaction.clearStoryItemsInexactMaxId(peerId: chat.peerId)
|
||||
}
|
||||
|
||||
@ -993,7 +993,8 @@ private final class AdminUserActionsSheetComponent: Component {
|
||||
maximumNumberOfLines: 0
|
||||
)),
|
||||
footer: nil,
|
||||
items: optionsSectionItems
|
||||
items: optionsSectionItems,
|
||||
isModal: true
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 100000.0)
|
||||
|
||||
@ -424,8 +424,11 @@ public final class ChatChannelSubscriberInputPanelNode: ChatInputPanelNode {
|
||||
let (title, _) = titleAndColorForAction(action, theme: interfaceState.theme, strings: interfaceState.strings)
|
||||
|
||||
var isAccent = false
|
||||
if case .join = self.action {
|
||||
switch self.action {
|
||||
case .join, .joinGroup, .applyToJoin:
|
||||
isAccent = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
centerAction = (title, isAccent)
|
||||
}
|
||||
|
||||
@ -1959,6 +1959,7 @@ private final class ChatSendStarsScreenComponent: Component {
|
||||
space: .local,
|
||||
id: 1
|
||||
),
|
||||
stableId: 0,
|
||||
author: liveStreamMessage.myPeer,
|
||||
text: liveStreamMessage.text.string,
|
||||
entities: entities,
|
||||
@ -1972,6 +1973,7 @@ private final class ChatSendStarsScreenComponent: Component {
|
||||
space: .local,
|
||||
id: 1
|
||||
),
|
||||
stableId: 0,
|
||||
author: reactData.myPeer,
|
||||
text: "",
|
||||
entities: [],
|
||||
|
||||
@ -409,22 +409,37 @@ public class GlassBackgroundView: UIView {
|
||||
let innerBackgroundRadius = min(innerBackgroundFrame.width, innerBackgroundFrame.height) * 0.5
|
||||
|
||||
let innerBackgroundView: UIView
|
||||
var innerBackgroundTransition = transition
|
||||
var animateIn = false
|
||||
if let current = self.innerBackgroundView {
|
||||
innerBackgroundView = current
|
||||
} else {
|
||||
innerBackgroundView = UIView()
|
||||
innerBackgroundTransition = innerBackgroundTransition.withAnimation(.none)
|
||||
self.innerBackgroundView = innerBackgroundView
|
||||
self.contentView.insertSubview(innerBackgroundView, at: 0)
|
||||
|
||||
innerBackgroundView.frame = innerBackgroundFrame
|
||||
innerBackgroundView.layer.cornerRadius = innerBackgroundRadius
|
||||
animateIn = true
|
||||
}
|
||||
|
||||
innerBackgroundView.backgroundColor = innerColor
|
||||
transition.setFrame(view: innerBackgroundView, frame: innerBackgroundFrame)
|
||||
transition.setCornerRadius(layer: innerBackgroundView.layer, cornerRadius: innerBackgroundRadius)
|
||||
innerBackgroundTransition.setFrame(view: innerBackgroundView, frame: innerBackgroundFrame)
|
||||
innerBackgroundTransition.setCornerRadius(layer: innerBackgroundView.layer, cornerRadius: innerBackgroundRadius)
|
||||
|
||||
if animateIn {
|
||||
transition.animateAlpha(view: innerBackgroundView, from: 0.0, to: 1.0)
|
||||
transition.animateScale(view: innerBackgroundView, from: 0.001, to: 1.0)
|
||||
}
|
||||
} else if let innerBackgroundView = self.innerBackgroundView {
|
||||
self.innerBackgroundView = nil
|
||||
|
||||
transition.setAlpha(view: innerBackgroundView, alpha: 0.0, completion: { [weak innerBackgroundView] _ in
|
||||
innerBackgroundView?.removeFromSuperview()
|
||||
})
|
||||
transition.setScale(view: innerBackgroundView, scale: 0.001)
|
||||
|
||||
innerBackgroundView.removeFromSuperview()
|
||||
}
|
||||
|
||||
|
||||
@ -218,6 +218,13 @@ public final class GlassControlPanelComponent: Component {
|
||||
if let leftItemFrame {
|
||||
centralLeftInset = leftItemFrame.maxX + minSpacing
|
||||
}
|
||||
|
||||
if centralRightInset <= 48.0 && centralLeftInset <= 48.0 {
|
||||
let maxInset = max(centralRightInset, centralLeftInset)
|
||||
centralLeftInset = maxInset
|
||||
centralRightInset = maxInset
|
||||
}
|
||||
|
||||
maxCentralItemSize.width = max(1.0, availableSize.width - centralLeftInset - centralRightInset)
|
||||
|
||||
let centralItemSize = centralItemComponent.update(
|
||||
|
||||
@ -331,15 +331,9 @@ public final class ListSectionComponent: Component {
|
||||
case legacy
|
||||
}
|
||||
|
||||
public enum BackgroundColor {
|
||||
case base
|
||||
case modal
|
||||
}
|
||||
|
||||
public let theme: PresentationTheme
|
||||
public let style: Style
|
||||
public let background: Background
|
||||
public let backgroundColor: BackgroundColor
|
||||
public let header: AnyComponent<Empty>?
|
||||
public let footer: AnyComponent<Empty>?
|
||||
public let items: [AnyComponentWithIdentity<Empty>]
|
||||
@ -351,7 +345,6 @@ public final class ListSectionComponent: Component {
|
||||
theme: PresentationTheme,
|
||||
style: Style = .legacy,
|
||||
background: Background = .all,
|
||||
backgroundColor: BackgroundColor = .base,
|
||||
header: AnyComponent<Empty>?,
|
||||
footer: AnyComponent<Empty>?,
|
||||
items: [AnyComponentWithIdentity<Empty>],
|
||||
@ -362,7 +355,6 @@ public final class ListSectionComponent: Component {
|
||||
self.theme = theme
|
||||
self.style = style
|
||||
self.background = background
|
||||
self.backgroundColor = backgroundColor
|
||||
self.header = header
|
||||
self.footer = footer
|
||||
self.items = items
|
||||
@ -381,9 +373,6 @@ public final class ListSectionComponent: Component {
|
||||
if lhs.background != rhs.background {
|
||||
return false
|
||||
}
|
||||
if lhs.backgroundColor != rhs.backgroundColor {
|
||||
return false
|
||||
}
|
||||
if lhs.header != rhs.header {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -798,7 +798,7 @@ final class StoryContentLiveChatComponent: Component {
|
||||
if let messagesState = self.messagesState {
|
||||
for message in messagesState.messages.reversed() {
|
||||
let messageId = message.id
|
||||
listItems.append(AnyComponentWithIdentity(id: message.id, component: AnyComponent(StoryLiveChatMessageComponent(
|
||||
listItems.append(AnyComponentWithIdentity(id: message.stableId, component: AnyComponent(StoryLiveChatMessageComponent(
|
||||
context: component.context,
|
||||
strings: component.strings,
|
||||
theme: component.theme,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user