mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Stories
This commit is contained in:
parent
af70f82faa
commit
d5561c092a
@ -979,6 +979,7 @@ private final class NotificationServiceHandler {
|
||||
case deleteMessage([MessageId])
|
||||
case readReactions([MessageId])
|
||||
case readMessage(MessageId)
|
||||
case readStories(peerId: PeerId, maxId: Int32)
|
||||
case call(CallData)
|
||||
}
|
||||
|
||||
@ -1030,6 +1031,14 @@ private final class NotificationServiceHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
case "READ_STORIES":
|
||||
if let peerId = peerId {
|
||||
if let storyIdString = payloadJson["max_id"] as? String {
|
||||
if let maxId = Int32(storyIdString) {
|
||||
action = .readStories(peerId: peerId, maxId: maxId)
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -1786,6 +1795,10 @@ private final class NotificationServiceHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let wasDisplayed = stateManager.postbox.transaction { transaction -> Bool in
|
||||
return _internal_getStoryNotificationWasDisplayed(transaction: transaction, id: StoryId(peerId: peerId, id: storyId))
|
||||
}
|
||||
|
||||
Logger.shared.log("NotificationService \(episode)", "Will fetch media")
|
||||
let _ = (combineLatest(queue: queue,
|
||||
@ -1794,10 +1807,11 @@ private final class NotificationServiceHandler {
|
||||
fetchNotificationSoundSignal
|
||||
|> timeout(10.0, queue: queue, alternate: .single(nil)),
|
||||
fetchStoriesSignal
|
||||
|> timeout(10.0, queue: queue, alternate: .single(Void()))
|
||||
|> timeout(10.0, queue: queue, alternate: .single(Void())),
|
||||
wasDisplayed
|
||||
)
|
||||
|> deliverOn(queue)).start(next: { mediaData, notificationSoundData, _ in
|
||||
guard let strongSelf = self, let _ = strongSelf.stateManager else {
|
||||
|> deliverOn(queue)).start(next: { mediaData, notificationSoundData, _, wasDisplayed in
|
||||
guard let strongSelf = self, let stateManager = strongSelf.stateManager else {
|
||||
completed()
|
||||
return
|
||||
}
|
||||
@ -1811,6 +1825,15 @@ private final class NotificationServiceHandler {
|
||||
let _ = try? notificationSoundData.write(to: URL(fileURLWithPath: filePath))
|
||||
}
|
||||
}
|
||||
|
||||
var content = content
|
||||
if wasDisplayed {
|
||||
content = NotificationContent(isLockedMessage: nil)
|
||||
} else {
|
||||
let _ = (stateManager.postbox.transaction { transaction -> Void in
|
||||
_internal_setStoryNotificationWasDisplayed(transaction: transaction, id: StoryId(peerId: peerId, id: storyId))
|
||||
}).start()
|
||||
}
|
||||
|
||||
Logger.shared.log("NotificationService \(episode)", "Updating content to \(content)")
|
||||
|
||||
@ -2003,6 +2026,39 @@ private final class NotificationServiceHandler {
|
||||
})
|
||||
}
|
||||
|
||||
if !removeIdentifiers.isEmpty {
|
||||
Logger.shared.log("NotificationService \(episode)", "Will try to remove \(removeIdentifiers.count) notifications")
|
||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removeIdentifiers)
|
||||
queue.after(1.0, {
|
||||
completeRemoval()
|
||||
})
|
||||
} else {
|
||||
completeRemoval()
|
||||
}
|
||||
})
|
||||
})
|
||||
case let .readStories(peerId, maxId):
|
||||
Logger.shared.log("NotificationService \(episode)", "Will read stories peerId: \(peerId) maxId: \(maxId)")
|
||||
let _ = (stateManager.postbox.transaction { transaction -> Void in
|
||||
}
|
||||
|> deliverOn(strongSelf.queue)).start(completed: {
|
||||
UNUserNotificationCenter.current().getDeliveredNotifications(completionHandler: { notifications in
|
||||
var removeIdentifiers: [String] = []
|
||||
for notification in notifications {
|
||||
if let peerIdString = notification.request.content.userInfo["peerId"] as? String, let peerIdValue = Int64(peerIdString), let messageIdString = notification.request.content.userInfo["story_id"] as? String, let messageIdValue = Int32(messageIdString) {
|
||||
if PeerId(peerIdValue) == peerId && messageIdValue <= maxId {
|
||||
removeIdentifiers.append(notification.request.identifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let completeRemoval: () -> Void = {
|
||||
let content = NotificationContent(isLockedMessage: nil)
|
||||
updateCurrentContent(content)
|
||||
|
||||
completed()
|
||||
}
|
||||
|
||||
if !removeIdentifiers.isEmpty {
|
||||
Logger.shared.log("NotificationService \(episode)", "Will try to remove \(removeIdentifiers.count) notifications")
|
||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removeIdentifiers)
|
||||
|
@ -953,6 +953,9 @@ public final class AvatarNode: ASDisplayNode {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let previousDisposable = self.loadingStatuses.copyItemsWithIndices().first(where: { $0.0 == index })?.1 {
|
||||
previousDisposable.dispose()
|
||||
}
|
||||
self.loadingStatuses.remove(index)
|
||||
if self.loadingStatuses.isEmpty {
|
||||
self.updateStoryIndicator(transition: .immediate)
|
||||
@ -964,6 +967,9 @@ public final class AvatarNode: ASDisplayNode {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
if let previousDisposable = self.loadingStatuses.copyItemsWithIndices().first(where: { $0.0 == index })?.1 {
|
||||
previousDisposable.dispose()
|
||||
}
|
||||
self.loadingStatuses.remove(index)
|
||||
if self.loadingStatuses.isEmpty {
|
||||
self.updateStoryIndicator(transition: .immediate)
|
||||
|
@ -207,6 +207,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
private var preloadStorySubscriptionsDisposable: Disposable?
|
||||
private var preloadStoryResourceDisposables: [MediaId: Disposable] = [:]
|
||||
|
||||
private var sharedOpenStoryProgressDisposable = MetaDisposable()
|
||||
|
||||
private var fullScreenEffectView: RippleEffectView?
|
||||
|
||||
public override func updateNavigationCustomData(_ data: Any?, progress: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
@ -778,6 +780,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
self.preloadStorySubscriptionsDisposable?.dispose()
|
||||
self.storyProgressDisposable?.dispose()
|
||||
self.storiesPostingAvailabilityDisposable?.dispose()
|
||||
self.sharedOpenStoryProgressDisposable.dispose()
|
||||
}
|
||||
|
||||
private func updateNavigationMetadata() {
|
||||
@ -1362,7 +1365,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
case .archive:
|
||||
StoryContainerScreen.openArchivedStories(context: self.context, parentController: self, avatarNode: itemNode.avatarNode)
|
||||
case let .peer(peerId):
|
||||
StoryContainerScreen.openPeerStories(context: self.context, peerId: peerId, parentController: self, avatarNode: itemNode.avatarNode)
|
||||
StoryContainerScreen.openPeerStories(context: self.context, peerId: peerId, parentController: self, avatarNode: itemNode.avatarNode, sharedProgressDisposable: self.sharedOpenStoryProgressDisposable)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,6 +107,7 @@ public struct Namespaces {
|
||||
public static let emojiSearchCategories: Int8 = 25
|
||||
public static let cachedEmojiQueryResults: Int8 = 26
|
||||
public static let cachedPeerStoryListHeads: Int8 = 27
|
||||
public static let displayedStoryNotifications: Int8 = 28
|
||||
}
|
||||
|
||||
public struct UnorderedItemList {
|
||||
|
@ -2061,3 +2061,17 @@ func _internal_enableStoryStealthMode(account: Account) -> Signal<Never, NoError
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
|
||||
public func _internal_getStoryNotificationWasDisplayed(transaction: Transaction, id: StoryId) -> Bool {
|
||||
let key = ValueBoxKey(length: 8 + 4)
|
||||
key.setInt64(0, value: id.peerId.toInt64())
|
||||
key.setInt32(8, value: id.id)
|
||||
return transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.displayedStoryNotifications, key: key)) != nil
|
||||
}
|
||||
|
||||
public func _internal_setStoryNotificationWasDisplayed(transaction: Transaction, id: StoryId) {
|
||||
let key = ValueBoxKey(length: 8 + 4)
|
||||
key.setInt64(0, value: id.peerId.toInt64())
|
||||
key.setInt32(8, value: id.id)
|
||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.displayedStoryNotifications, key: key), entry: CodableEntry(data: Data()))
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ public extension StoryContainerScreen {
|
||||
let _ = avatarNode.pushLoadingStatus(signal: signal)
|
||||
}
|
||||
|
||||
static func openPeerStories(context: AccountContext, peerId: EnginePeer.Id, parentController: ViewController, avatarNode: AvatarNode) {
|
||||
static func openPeerStories(context: AccountContext, peerId: EnginePeer.Id, parentController: ViewController, avatarNode: AvatarNode, sharedProgressDisposable: MetaDisposable? = nil) {
|
||||
return openPeerStoriesCustom(
|
||||
context: context,
|
||||
peerId: peerId,
|
||||
@ -149,7 +149,7 @@ public extension StoryContainerScreen {
|
||||
guard let avatarNode else {
|
||||
return
|
||||
}
|
||||
let _ = avatarNode.pushLoadingStatus(signal: signal)
|
||||
sharedProgressDisposable?.set(avatarNode.pushLoadingStatus(signal: signal))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -2434,6 +2434,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
soundImage = "Stories/SoundOn"
|
||||
}
|
||||
|
||||
//TODO:anim_storymute
|
||||
let soundButtonSize = self.soundButton.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(PlainButtonComponent(
|
||||
|
Loading…
x
Reference in New Issue
Block a user