This commit is contained in:
Ali 2023-07-12 23:52:56 +04:00
parent ca8555c070
commit ff9157fef4
3 changed files with 209 additions and 191 deletions

View File

@ -265,6 +265,7 @@
"PUSH_STORY_NOTEXT" = "%1$@|posted a story"; "PUSH_STORY_NOTEXT" = "%1$@|posted a story";
"PUSH_MESSAGE_STORY" = "%1$@|shared a story with you"; "PUSH_MESSAGE_STORY" = "%1$@|shared a story with you";
"PUSH_MESSAGE_STORY_MENTION" = "%1$@|mentioned you in a story";
"PUSH_CHANNEL_MESSAGE_STORY" = "%1$@|shared a story"; "PUSH_CHANNEL_MESSAGE_STORY" = "%1$@|shared a story";
"PUSH_CHAT_MESSAGE_STORY" = "%2$@|%1$@ shared a story to the group"; "PUSH_CHAT_MESSAGE_STORY" = "%2$@|%1$@ shared a story to the group";

View File

@ -629,221 +629,238 @@ public extension TelegramEngine {
}).start() }).start()
} }
public func storySubscriptions(isHidden: Bool) -> Signal<EngineStorySubscriptions, NoError> { public func storySubscriptions(isHidden: Bool, tempKeepNewlyArchived: Bool = false) -> Signal<EngineStorySubscriptions, NoError> {
let debugTimerSignal: Signal<Bool, NoError> return `deferred` { () -> Signal<EngineStorySubscriptions, NoError> in
#if DEBUG && false let debugTimerSignal: Signal<Bool, NoError>
debugTimerSignal = Signal<Bool, NoError>.single(true) #if DEBUG && false
|> then( debugTimerSignal = Signal<Bool, NoError>.single(true)
Signal<Bool, NoError>.single(true)
|> delay(1.0, queue: .mainQueue())
|> then( |> then(
Signal<Bool, NoError>.single(false) Signal<Bool, NoError>.single(true)
|> delay(1.0, queue: .mainQueue()) |> delay(1.0, queue: .mainQueue())
) |> then(
|> restart Signal<Bool, NoError>.single(false)
) |> delay(1.0, queue: .mainQueue())
#else
debugTimerSignal = .single(true)
#endif
let subscriptionsKey: PostboxStorySubscriptionsKey = isHidden ? .hidden : .filtered
let basicPeerKey = PostboxViewKey.basicPeer(self.account.peerId)
let storySubscriptionsKey = PostboxViewKey.storySubscriptions(key: subscriptionsKey)
return combineLatest(debugTimerSignal |> distinctUntilChanged,
self.account.postbox.combinedView(keys: [
basicPeerKey,
storySubscriptionsKey,
PostboxViewKey.storiesState(key: .subscriptions(subscriptionsKey))
]))
|> mapToSignal { debugTimer, views -> Signal<EngineStorySubscriptions, NoError> in
guard let basicPeerView = views.views[basicPeerKey] as? BasicPeerView, let accountPeer = basicPeerView.peer else {
return .single(EngineStorySubscriptions(accountItem: nil, items: [], hasMoreToken: nil))
}
guard let storySubscriptionsView = views.views[storySubscriptionsKey] as? StorySubscriptionsView else {
return .single(EngineStorySubscriptions(accountItem: nil, items: [], hasMoreToken: nil))
}
guard let storiesStateView = views.views[PostboxViewKey.storiesState(key: .subscriptions(subscriptionsKey))] as? StoryStatesView else {
return .single(EngineStorySubscriptions(accountItem: nil, items: [], hasMoreToken: nil))
}
var additionalDataKeys: [PostboxViewKey] = []
additionalDataKeys.append(PostboxViewKey.storyItems(peerId: self.account.peerId))
additionalDataKeys.append(PostboxViewKey.storiesState(key: .peer(self.account.peerId)))
additionalDataKeys.append(PostboxViewKey.storiesState(key: .local))
var subscriptionPeerIds = storySubscriptionsView.peerIds.filter { $0 != self.account.peerId }
if !debugTimer {
subscriptionPeerIds.removeAll()
}
additionalDataKeys.append(contentsOf: subscriptionPeerIds.map { peerId -> PostboxViewKey in
return PostboxViewKey.storyItems(peerId: peerId)
})
additionalDataKeys.append(contentsOf: subscriptionPeerIds.map { peerId -> PostboxViewKey in
return PostboxViewKey.storiesState(key: .peer(peerId))
})
additionalDataKeys.append(contentsOf: subscriptionPeerIds.map { peerId -> PostboxViewKey in
return PostboxViewKey.basicPeer(peerId)
})
return self.account.postbox.combinedView(keys: additionalDataKeys)
|> map { views -> EngineStorySubscriptions in
let _ = accountPeer
var hasMoreToken: String?
if let subscriptionsState = storiesStateView.value?.get(Stories.SubscriptionsState.self) {
if subscriptionsState.hasMore {
hasMoreToken = subscriptionsState.opaqueState + "_\(subscriptionsState.refreshId)"
} else {
hasMoreToken = nil
}
} else {
hasMoreToken = ""
}
var accountPendingItemCount = 0
if let view = views.views[PostboxViewKey.storiesState(key: .local)] as? StoryStatesView, let localState = view.value?.get(Stories.LocalState.self) {
accountPendingItemCount = localState.items.count
}
var accountItem: EngineStorySubscriptions.Item = EngineStorySubscriptions.Item(
peer: EnginePeer(accountPeer),
hasUnseen: false,
hasUnseenCloseFriends: false,
hasPending: accountPendingItemCount != 0,
storyCount: accountPendingItemCount,
unseenCount: 0,
lastTimestamp: 0
) )
|> restart
)
#else
debugTimerSignal = .single(true)
#endif
let previousIdList = Atomic<Set<PeerId>>(value: Set())
let subscriptionsKey: PostboxStorySubscriptionsKey = isHidden ? .hidden : .filtered
let basicPeerKey = PostboxViewKey.basicPeer(self.account.peerId)
let storySubscriptionsKey = PostboxViewKey.storySubscriptions(key: subscriptionsKey)
return combineLatest(debugTimerSignal |> distinctUntilChanged,
self.account.postbox.combinedView(keys: [
basicPeerKey,
storySubscriptionsKey,
PostboxViewKey.storiesState(key: .subscriptions(subscriptionsKey))
]))
|> mapToSignal { debugTimer, views -> Signal<EngineStorySubscriptions, NoError> in
guard let basicPeerView = views.views[basicPeerKey] as? BasicPeerView, let accountPeer = basicPeerView.peer else {
return .single(EngineStorySubscriptions(accountItem: nil, items: [], hasMoreToken: nil))
}
guard let storySubscriptionsView = views.views[storySubscriptionsKey] as? StorySubscriptionsView else {
return .single(EngineStorySubscriptions(accountItem: nil, items: [], hasMoreToken: nil))
}
guard let storiesStateView = views.views[PostboxViewKey.storiesState(key: .subscriptions(subscriptionsKey))] as? StoryStatesView else {
return .single(EngineStorySubscriptions(accountItem: nil, items: [], hasMoreToken: nil))
}
var items: [EngineStorySubscriptions.Item] = [] var additionalDataKeys: [PostboxViewKey] = []
do { additionalDataKeys.append(PostboxViewKey.storyItems(peerId: self.account.peerId))
let peerId = self.account.peerId additionalDataKeys.append(PostboxViewKey.storiesState(key: .peer(self.account.peerId)))
additionalDataKeys.append(PostboxViewKey.storiesState(key: .local))
var subscriptionPeerIds = storySubscriptionsView.peerIds.filter { $0 != self.account.peerId }
if !debugTimer {
subscriptionPeerIds.removeAll()
}
if tempKeepNewlyArchived {
let updatedList = previousIdList.modify { list in
var list = list
list.formUnion(subscriptionPeerIds)
return list
}
for id in updatedList {
if !subscriptionPeerIds.contains(id) {
subscriptionPeerIds.append(id)
}
}
}
additionalDataKeys.append(contentsOf: subscriptionPeerIds.map { peerId -> PostboxViewKey in
return PostboxViewKey.storyItems(peerId: peerId)
})
additionalDataKeys.append(contentsOf: subscriptionPeerIds.map { peerId -> PostboxViewKey in
return PostboxViewKey.storiesState(key: .peer(peerId))
})
additionalDataKeys.append(contentsOf: subscriptionPeerIds.map { peerId -> PostboxViewKey in
return PostboxViewKey.basicPeer(peerId)
})
return self.account.postbox.combinedView(keys: additionalDataKeys)
|> map { views -> EngineStorySubscriptions in
let _ = accountPeer
if let itemsView = views.views[PostboxViewKey.storyItems(peerId: peerId)] as? StoryItemsView, let stateView = views.views[PostboxViewKey.storiesState(key: .peer(peerId))] as? StoryStatesView { var hasMoreToken: String?
if let lastEntry = itemsView.items.last?.value.get(Stories.StoredItem.self) { if let subscriptionsState = storiesStateView.value?.get(Stories.SubscriptionsState.self) {
let peerState: Stories.PeerState? = stateView.value?.get(Stories.PeerState.self) if subscriptionsState.hasMore {
var hasUnseen = false hasMoreToken = subscriptionsState.opaqueState + "_\(subscriptionsState.refreshId)"
var hasUnseenCloseFriends = false } else {
var unseenCount = 0 hasMoreToken = nil
if let peerState = peerState { }
hasUnseen = peerState.maxReadId < lastEntry.id } else {
hasMoreToken = ""
for item in itemsView.items { }
if item.id > peerState.maxReadId {
unseenCount += 1 var accountPendingItemCount = 0
} if let view = views.views[PostboxViewKey.storiesState(key: .local)] as? StoryStatesView, let localState = view.value?.get(Stories.LocalState.self) {
accountPendingItemCount = localState.items.count
}
var accountItem: EngineStorySubscriptions.Item = EngineStorySubscriptions.Item(
peer: EnginePeer(accountPeer),
hasUnseen: false,
hasUnseenCloseFriends: false,
hasPending: accountPendingItemCount != 0,
storyCount: accountPendingItemCount,
unseenCount: 0,
lastTimestamp: 0
)
var items: [EngineStorySubscriptions.Item] = []
do {
let peerId = self.account.peerId
if let itemsView = views.views[PostboxViewKey.storyItems(peerId: peerId)] as? StoryItemsView, let stateView = views.views[PostboxViewKey.storiesState(key: .peer(peerId))] as? StoryStatesView {
if let lastEntry = itemsView.items.last?.value.get(Stories.StoredItem.self) {
let peerState: Stories.PeerState? = stateView.value?.get(Stories.PeerState.self)
var hasUnseen = false
var hasUnseenCloseFriends = false
var unseenCount = 0
if let peerState = peerState {
hasUnseen = peerState.maxReadId < lastEntry.id
if case let .item(item) = item.value.get(Stories.StoredItem.self) { for item in itemsView.items {
if item.id > peerState.maxReadId { if item.id > peerState.maxReadId {
if item.isCloseFriends { unseenCount += 1
hasUnseenCloseFriends = true }
if case let .item(item) = item.value.get(Stories.StoredItem.self) {
if item.id > peerState.maxReadId {
if item.isCloseFriends {
hasUnseenCloseFriends = true
}
} }
} }
} }
} }
let item = EngineStorySubscriptions.Item(
peer: EnginePeer(accountPeer),
hasUnseen: hasUnseen,
hasUnseenCloseFriends: hasUnseenCloseFriends,
hasPending: accountPendingItemCount != 0,
storyCount: itemsView.items.count + accountPendingItemCount,
unseenCount: unseenCount,
lastTimestamp: lastEntry.timestamp
)
accountItem = item
} }
let item = EngineStorySubscriptions.Item(
peer: EnginePeer(accountPeer),
hasUnseen: hasUnseen,
hasUnseenCloseFriends: hasUnseenCloseFriends,
hasPending: accountPendingItemCount != 0,
storyCount: itemsView.items.count + accountPendingItemCount,
unseenCount: unseenCount,
lastTimestamp: lastEntry.timestamp
)
accountItem = item
} }
} }
}
for peerId in subscriptionPeerIds {
guard let peerView = views.views[PostboxViewKey.basicPeer(peerId)] as? BasicPeerView else {
continue
}
guard let peer = peerView.peer else {
continue
}
guard let itemsView = views.views[PostboxViewKey.storyItems(peerId: peerId)] as? StoryItemsView else {
continue
}
guard let stateView = views.views[PostboxViewKey.storiesState(key: .peer(peerId))] as? StoryStatesView else {
continue
}
guard let lastEntry = itemsView.items.last?.value.get(Stories.StoredItem.self) else {
continue
}
let peerState: Stories.PeerState? = stateView.value?.get(Stories.PeerState.self) for peerId in subscriptionPeerIds {
var hasUnseen = false guard let peerView = views.views[PostboxViewKey.basicPeer(peerId)] as? BasicPeerView else {
var hasUnseenCloseFriends = false continue
var unseenCount = 0 }
if let peerState = peerState { guard let peer = peerView.peer else {
hasUnseen = peerState.maxReadId < lastEntry.id continue
}
guard let itemsView = views.views[PostboxViewKey.storyItems(peerId: peerId)] as? StoryItemsView else {
continue
}
guard let stateView = views.views[PostboxViewKey.storiesState(key: .peer(peerId))] as? StoryStatesView else {
continue
}
guard let lastEntry = itemsView.items.last?.value.get(Stories.StoredItem.self) else {
continue
}
for item in itemsView.items { let peerState: Stories.PeerState? = stateView.value?.get(Stories.PeerState.self)
if item.id > peerState.maxReadId { var hasUnseen = false
unseenCount += 1 var hasUnseenCloseFriends = false
var unseenCount = 0
if case let .item(item) = item.value.get(Stories.StoredItem.self) { if let peerState = peerState {
if item.isCloseFriends { hasUnseen = peerState.maxReadId < lastEntry.id
hasUnseenCloseFriends = true
for item in itemsView.items {
if item.id > peerState.maxReadId {
unseenCount += 1
if case let .item(item) = item.value.get(Stories.StoredItem.self) {
if item.isCloseFriends {
hasUnseenCloseFriends = true
}
} }
} }
} }
} }
let item = EngineStorySubscriptions.Item(
peer: EnginePeer(peer),
hasUnseen: hasUnseen,
hasUnseenCloseFriends: hasUnseenCloseFriends,
hasPending: false,
storyCount: itemsView.items.count,
unseenCount: unseenCount,
lastTimestamp: lastEntry.timestamp
)
if peerId == accountPeer.id {
accountItem = item
} else {
items.append(item)
}
} }
let item = EngineStorySubscriptions.Item( items.sort(by: { lhs, rhs in
peer: EnginePeer(peer), if lhs.hasUnseen != rhs.hasUnseen {
hasUnseen: hasUnseen, if lhs.hasUnseen {
hasUnseenCloseFriends: hasUnseenCloseFriends, return true
hasPending: false, } else {
storyCount: itemsView.items.count, return false
unseenCount: unseenCount, }
lastTimestamp: lastEntry.timestamp }
) if lhs.peer.isService != rhs.peer.isService {
if lhs.peer.isService {
return true
} else {
return false
}
}
if lhs.peer.isPremium != rhs.peer.isPremium {
if lhs.peer.isPremium {
return true
} else {
return false
}
}
if lhs.lastTimestamp != rhs.lastTimestamp {
return lhs.lastTimestamp > rhs.lastTimestamp
}
return lhs.peer.id < rhs.peer.id
})
if peerId == accountPeer.id { return EngineStorySubscriptions(accountItem: accountItem, items: items, hasMoreToken: hasMoreToken)
accountItem = item
} else {
items.append(item)
}
} }
items.sort(by: { lhs, rhs in
if lhs.hasUnseen != rhs.hasUnseen {
if lhs.hasUnseen {
return true
} else {
return false
}
}
if lhs.peer.isService != rhs.peer.isService {
if lhs.peer.isService {
return true
} else {
return false
}
}
if lhs.peer.isPremium != rhs.peer.isPremium {
if lhs.peer.isPremium {
return true
} else {
return false
}
}
if lhs.lastTimestamp != rhs.lastTimestamp {
return lhs.lastTimestamp > rhs.lastTimestamp
}
return lhs.peer.id < rhs.peer.id
})
return EngineStorySubscriptions(accountItem: accountItem, items: items, hasMoreToken: hasMoreToken)
} }
} }
} }

View File

@ -553,7 +553,7 @@ public final class StoryContentContextImpl: StoryContentContext {
self.updatePeerContexts() self.updatePeerContexts()
}) })
} else { } else {
self.storySubscriptionsDisposable = (context.engine.messages.storySubscriptions(isHidden: isHidden) self.storySubscriptionsDisposable = (context.engine.messages.storySubscriptions(isHidden: isHidden, tempKeepNewlyArchived: true)
|> deliverOnMainQueue).start(next: { [weak self] storySubscriptions in |> deliverOnMainQueue).start(next: { [weak self] storySubscriptions in
guard let self else { guard let self else {
return return