[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

@@ -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))
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)
}
case let .UpdateStory(peerId, story):
var updatedPeerEntries: [StoryItemsTableEntry] = transaction.getStoryItems(peerId: peerId)
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)
}
}