[WIP] Stories

This commit is contained in:
Ali 2023-05-31 21:26:08 +04:00
parent 54dc2eae57
commit e0f74e813f
8 changed files with 89 additions and 84 deletions

View File

@ -909,7 +909,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-337352679] = { return Api.Update.parse_updateServiceNotification($0) }
dict[834816008] = { return Api.Update.parse_updateStickerSets($0) }
dict[196268545] = { return Api.Update.parse_updateStickerSetsOrder($0) }
dict[1727715253] = { return Api.Update.parse_updateStories($0) }
dict[542785843] = { return Api.Update.parse_updateStory($0) }
dict[468923833] = { return Api.Update.parse_updateStoryID($0) }
dict[-2112423005] = { return Api.Update.parse_updateTheme($0) }
dict[8703322] = { return Api.Update.parse_updateTranscribedAudio($0) }

View File

@ -1038,7 +1038,7 @@ public extension Api {
case updateServiceNotification(flags: Int32, inboxDate: Int32?, type: String, message: String, media: Api.MessageMedia, entities: [Api.MessageEntity])
case updateStickerSets(flags: Int32)
case updateStickerSetsOrder(flags: Int32, order: [Int64])
case updateStories(stories: Api.UserStories)
case updateStory(userId: Int64, story: Api.StoryItem)
case updateStoryID(id: Int32, randomId: Int64)
case updateTheme(theme: Api.Theme)
case updateTranscribedAudio(flags: Int32, peer: Api.Peer, msgId: Int32, transcriptionId: Int64, text: String)
@ -1939,11 +1939,12 @@ public extension Api {
serializeInt64(item, buffer: buffer, boxed: false)
}
break
case .updateStories(let stories):
case .updateStory(let userId, let story):
if boxed {
buffer.appendInt32(1727715253)
buffer.appendInt32(542785843)
}
stories.serialize(buffer, true)
serializeInt64(userId, buffer: buffer, boxed: false)
story.serialize(buffer, true)
break
case .updateStoryID(let id, let randomId):
if boxed {
@ -2238,8 +2239,8 @@ public extension Api {
return ("updateStickerSets", [("flags", flags as Any)])
case .updateStickerSetsOrder(let flags, let order):
return ("updateStickerSetsOrder", [("flags", flags as Any), ("order", order as Any)])
case .updateStories(let stories):
return ("updateStories", [("stories", stories as Any)])
case .updateStory(let userId, let story):
return ("updateStory", [("userId", userId as Any), ("story", story as Any)])
case .updateStoryID(let id, let randomId):
return ("updateStoryID", [("id", id as Any), ("randomId", randomId as Any)])
case .updateTheme(let theme):
@ -4029,14 +4030,17 @@ public extension Api {
return nil
}
}
public static func parse_updateStories(_ reader: BufferReader) -> Update? {
var _1: Api.UserStories?
public static func parse_updateStory(_ reader: BufferReader) -> Update? {
var _1: Int64?
_1 = reader.readInt64()
var _2: Api.StoryItem?
if let signature = reader.readInt32() {
_1 = Api.parse(reader, signature: signature) as? Api.UserStories
_2 = Api.parse(reader, signature: signature) as? Api.StoryItem
}
let _c1 = _1 != nil
if _c1 {
return Api.Update.updateStories(stories: _1!)
let _c2 = _2 != nil
if _c1 && _c2 {
return Api.Update.updateStory(userId: _1!, story: _2!)
}
else {
return nil

View File

@ -3542,6 +3542,22 @@ public extension Api.functions.contacts {
})
}
}
public extension Api.functions.contacts {
static func toggleStoriesHidden(id: Api.InputUser, hidden: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()
buffer.appendInt32(1967110245)
id.serialize(buffer, true)
hidden.serialize(buffer, true)
return (FunctionDescription(name: "contacts.toggleStoriesHidden", parameters: [("id", String(describing: id)), ("hidden", String(describing: hidden))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer)
var result: Api.Bool?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Bool
}
return result
})
}
}
public extension Api.functions.contacts {
static func toggleTopPeers(enabled: Api.Bool) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer()

View File

@ -120,7 +120,7 @@ enum AccountStateMutationOperation {
case UpdateConfig
case UpdateExtendedMedia(MessageId, Api.MessageExtendedMedia)
case ResetForumTopic(topicId: MessageId, data: StoreMessageHistoryThreadData, pts: Int32)
case UpdateStories(Api.UserStories)
case UpdateStory(peerId: PeerId, story: Api.StoryItem)
case UpdateReadStories(peerId: PeerId, maxId: Int32)
}
@ -612,8 +612,8 @@ struct AccountMutableState {
self.addOperation(.UpdateExtendedMedia(messageId, extendedMedia))
}
mutating func updateStories(stories: Api.UserStories) {
self.addOperation(.UpdateStories(stories))
mutating func updateStory(peerId: PeerId, story: Api.StoryItem) {
self.addOperation(.UpdateStory(peerId: peerId, story: story))
}
mutating func readStories(peerId: PeerId, maxId: Int32) {
@ -622,7 +622,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStories, .UpdateReadStories:
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories:
break
case let .AddMessages(messages, location):
for message in messages {

View File

@ -1628,8 +1628,8 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
updatedState.reloadConfig()
case let .updateMessageExtendedMedia(peer, msgId, extendedMedia):
updatedState.updateExtendedMedia(MessageId(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, id: msgId), extendedMedia: extendedMedia)
case let .updateStories(stories):
updatedState.updateStories(stories: stories)
case let .updateStory(userId, story):
updatedState.updateStory(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), story: story)
case let .updateReadStories(userId, id):
updatedState.readStories(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)), maxId: id)
default:
@ -3004,7 +3004,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddScheduledMessages: OptimizeAddMessagesState?
for operation in operations {
switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStories, .UpdateReadStories:
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic, .UpdateStory, .UpdateReadStories:
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
}
@ -4328,62 +4328,53 @@ func replayFinalState(
transaction.replaceMessageTagSummary(peerId: topicId.peerId, threadId: Int64(topicId.id), tagMask: .unseenPersonalMessage, namespace: Namespaces.Message.Cloud, count: data.unreadMentionCount, maxId: data.topMessageId)
transaction.replaceMessageTagSummary(peerId: topicId.peerId, threadId: Int64(topicId.id), tagMask: .unseenReaction, namespace: Namespaces.Message.Cloud, count: data.unreadReactionCount, maxId: data.topMessageId)
}
case let .UpdateStories(updateStories):
switch updateStories {
case let .userStories(_, userId, maxReadId, stories):
let peerId = PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))
case let .UpdateStory(peerId, story):
var updatedPeerEntries: [StoryItemsTableEntry] = transaction.getStoryItems(peerId: peerId)
var updatedPeerEntries: [StoryItemsTableEntry] = transaction.getStoryItems(peerId: peerId)
for story in stories {
if let storedItem = Stories.StoredItem(apiStoryItem: story, peerId: peerId, transaction: transaction) {
if let currentIndex = updatedPeerEntries.firstIndex(where: { $0.id == storedItem.id }) {
if case .item = storedItem {
if let codedEntry = CodableEntry(storedItem) {
updatedPeerEntries[currentIndex] = StoryItemsTableEntry(value: codedEntry, id: storedItem.id)
}
}
} else {
if let codedEntry = CodableEntry(storedItem) {
updatedPeerEntries.append(StoryItemsTableEntry(value: codedEntry, id: storedItem.id))
}
}
} else {
if case let .storyItemDeleted(id) = story {
if let index = updatedPeerEntries.firstIndex(where: { $0.id == id }) {
updatedPeerEntries.remove(at: index)
}
if let storedItem = Stories.StoredItem(apiStoryItem: story, peerId: peerId, transaction: transaction) {
if let currentIndex = updatedPeerEntries.firstIndex(where: { $0.id == storedItem.id }) {
if case .item = storedItem {
if let codedEntry = CodableEntry(storedItem) {
updatedPeerEntries[currentIndex] = StoryItemsTableEntry(value: codedEntry, id: storedItem.id)
}
}
}
var subscriptionsOpaqueState: String?
if let state = transaction.getSubscriptionsStoriesState()?.get(Stories.SubscriptionsState.self) {
subscriptionsOpaqueState = state.opaqueState
}
var appliedMaxReadId = maxReadId
if let currentState = transaction.getPeerStoryState(peerId: peerId)?.get(Stories.PeerState.self) {
if let appliedMaxReadIdValue = appliedMaxReadId {
appliedMaxReadId = max(appliedMaxReadIdValue, currentState.maxReadId)
} else {
appliedMaxReadId = currentState.maxReadId
} else {
if let codedEntry = CodableEntry(storedItem) {
updatedPeerEntries.append(StoryItemsTableEntry(value: codedEntry, id: storedItem.id))
}
}
transaction.setStoryItems(peerId: peerId, items: updatedPeerEntries)
transaction.setPeerStoryState(peerId: peerId, state: CodableEntry(Stories.PeerState(
subscriptionsOpaqueState: subscriptionsOpaqueState,
maxReadId: appliedMaxReadId ?? 0
)))
for storyItem in stories {
if let parsedItem = Stories.StoredItem(apiStoryItem: storyItem, peerId: peerId, transaction: transaction) {
storyUpdates.append(InternalStoryUpdate.added(peerId: peerId, item: parsedItem))
} else {
storyUpdates.append(InternalStoryUpdate.deleted(peerId: peerId, id: storyItem.id))
} else {
if case let .storyItemDeleted(id) = story {
if let index = updatedPeerEntries.firstIndex(where: { $0.id == id }) {
updatedPeerEntries.remove(at: index)
}
}
}
var subscriptionsOpaqueState: String?
if let state = transaction.getSubscriptionsStoriesState()?.get(Stories.SubscriptionsState.self) {
subscriptionsOpaqueState = state.opaqueState
}
var appliedMaxReadId: Int32?
if let currentState = transaction.getPeerStoryState(peerId: peerId)?.get(Stories.PeerState.self) {
if let appliedMaxReadIdValue = appliedMaxReadId {
appliedMaxReadId = max(appliedMaxReadIdValue, currentState.maxReadId)
} else {
appliedMaxReadId = currentState.maxReadId
}
}
transaction.setStoryItems(peerId: peerId, items: updatedPeerEntries)
transaction.setPeerStoryState(peerId: peerId, state: CodableEntry(Stories.PeerState(
subscriptionsOpaqueState: subscriptionsOpaqueState,
maxReadId: appliedMaxReadId ?? 0
)))
if let parsedItem = Stories.StoredItem(apiStoryItem: story, peerId: peerId, transaction: transaction) {
storyUpdates.append(InternalStoryUpdate.added(peerId: peerId, item: parsedItem))
} else {
storyUpdates.append(InternalStoryUpdate.deleted(peerId: peerId, id: story.id))
}
case let .UpdateReadStories(peerId, maxId):
var appliedMaxReadId = maxId
if let currentState = transaction.getPeerStoryState(peerId: peerId)?.get(Stories.PeerState.self) {

View File

@ -644,20 +644,15 @@ func _internal_uploadStory(account: Account, media: EngineStoryInputMedia, text:
|> mapToSignal { updates -> Signal<Never, NoError> in
if let updates = updates {
for update in updates.allUpdates {
if case let .updateStories(stories) = update {
switch stories {
case let .userStories(_, userId, _, apiStories):
if PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId)) == account.peerId, apiStories.count == 1 {
switch apiStories[0] {
case let .storyItem(_, _, _, _, _, media, _, _):
let (parsedMedia, _, _, _) = textMediaAndExpirationTimerFromApiMedia(media, account.peerId)
if let parsedMedia = parsedMedia {
applyMediaResourceChanges(from: originalMedia, to: parsedMedia, postbox: account.postbox, force: false)
}
default:
break
}
if case let .updateStory(_, story) = update {
switch story {
case let .storyItem(_, _, _, _, _, media, _, _):
let (parsedMedia, _, _, _) = textMediaAndExpirationTimerFromApiMedia(media, account.peerId)
if let parsedMedia = parsedMedia {
applyMediaResourceChanges(from: originalMedia, to: parsedMedia, postbox: account.postbox, force: false)
}
default:
break
}
}
}

View File

@ -796,7 +796,7 @@ public extension TelegramEngine {
let peerState: Stories.PeerState? = stateView.value?.get(Stories.PeerState.self)
if let peerState = peerState {
if let item = itemsView.items.first(where: { $0.id >= peerState.maxReadId }) {
if let item = itemsView.items.first(where: { $0.id > peerState.maxReadId }) {
nextItem = item.value.get(Stories.StoredItem.self)
}
}

View File

@ -155,8 +155,7 @@ final class StoryContentCaptionComponent: Component {
transition: .immediate,
component: AnyComponent(MultilineTextComponent(
text: .plain(NSAttributedString(string: component.text, font: Font.regular(16.0), textColor: .white)),
maximumNumberOfLines: 0,
textShadowColor: UIColor(white: 0.0, alpha: 0.3)
maximumNumberOfLines: 0
)),
environment: {},
containerSize: textContainerSize