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 deleteMessage([MessageId])
|
||||||
case readReactions([MessageId])
|
case readReactions([MessageId])
|
||||||
case readMessage(MessageId)
|
case readMessage(MessageId)
|
||||||
|
case readStories(peerId: PeerId, maxId: Int32)
|
||||||
case call(CallData)
|
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:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -1787,6 +1796,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")
|
Logger.shared.log("NotificationService \(episode)", "Will fetch media")
|
||||||
let _ = (combineLatest(queue: queue,
|
let _ = (combineLatest(queue: queue,
|
||||||
fetchMediaSignal
|
fetchMediaSignal
|
||||||
@ -1794,10 +1807,11 @@ private final class NotificationServiceHandler {
|
|||||||
fetchNotificationSoundSignal
|
fetchNotificationSoundSignal
|
||||||
|> timeout(10.0, queue: queue, alternate: .single(nil)),
|
|> timeout(10.0, queue: queue, alternate: .single(nil)),
|
||||||
fetchStoriesSignal
|
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
|
|> deliverOn(queue)).start(next: { mediaData, notificationSoundData, _, wasDisplayed in
|
||||||
guard let strongSelf = self, let _ = strongSelf.stateManager else {
|
guard let strongSelf = self, let stateManager = strongSelf.stateManager else {
|
||||||
completed()
|
completed()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1812,6 +1826,15 @@ private final class NotificationServiceHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)")
|
Logger.shared.log("NotificationService \(episode)", "Updating content to \(content)")
|
||||||
|
|
||||||
updateCurrentContent(content)
|
updateCurrentContent(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 {
|
if !removeIdentifiers.isEmpty {
|
||||||
Logger.shared.log("NotificationService \(episode)", "Will try to remove \(removeIdentifiers.count) notifications")
|
Logger.shared.log("NotificationService \(episode)", "Will try to remove \(removeIdentifiers.count) notifications")
|
||||||
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removeIdentifiers)
|
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removeIdentifiers)
|
||||||
|
@ -953,6 +953,9 @@ public final class AvatarNode: ASDisplayNode {
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if let previousDisposable = self.loadingStatuses.copyItemsWithIndices().first(where: { $0.0 == index })?.1 {
|
||||||
|
previousDisposable.dispose()
|
||||||
|
}
|
||||||
self.loadingStatuses.remove(index)
|
self.loadingStatuses.remove(index)
|
||||||
if self.loadingStatuses.isEmpty {
|
if self.loadingStatuses.isEmpty {
|
||||||
self.updateStoryIndicator(transition: .immediate)
|
self.updateStoryIndicator(transition: .immediate)
|
||||||
@ -964,6 +967,9 @@ public final class AvatarNode: ASDisplayNode {
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if let previousDisposable = self.loadingStatuses.copyItemsWithIndices().first(where: { $0.0 == index })?.1 {
|
||||||
|
previousDisposable.dispose()
|
||||||
|
}
|
||||||
self.loadingStatuses.remove(index)
|
self.loadingStatuses.remove(index)
|
||||||
if self.loadingStatuses.isEmpty {
|
if self.loadingStatuses.isEmpty {
|
||||||
self.updateStoryIndicator(transition: .immediate)
|
self.updateStoryIndicator(transition: .immediate)
|
||||||
|
@ -207,6 +207,8 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
private var preloadStorySubscriptionsDisposable: Disposable?
|
private var preloadStorySubscriptionsDisposable: Disposable?
|
||||||
private var preloadStoryResourceDisposables: [MediaId: Disposable] = [:]
|
private var preloadStoryResourceDisposables: [MediaId: Disposable] = [:]
|
||||||
|
|
||||||
|
private var sharedOpenStoryProgressDisposable = MetaDisposable()
|
||||||
|
|
||||||
private var fullScreenEffectView: RippleEffectView?
|
private var fullScreenEffectView: RippleEffectView?
|
||||||
|
|
||||||
public override func updateNavigationCustomData(_ data: Any?, progress: CGFloat, transition: ContainedViewLayoutTransition) {
|
public override func updateNavigationCustomData(_ data: Any?, progress: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||||
@ -778,6 +780,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
self.preloadStorySubscriptionsDisposable?.dispose()
|
self.preloadStorySubscriptionsDisposable?.dispose()
|
||||||
self.storyProgressDisposable?.dispose()
|
self.storyProgressDisposable?.dispose()
|
||||||
self.storiesPostingAvailabilityDisposable?.dispose()
|
self.storiesPostingAvailabilityDisposable?.dispose()
|
||||||
|
self.sharedOpenStoryProgressDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateNavigationMetadata() {
|
private func updateNavigationMetadata() {
|
||||||
@ -1362,7 +1365,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
case .archive:
|
case .archive:
|
||||||
StoryContainerScreen.openArchivedStories(context: self.context, parentController: self, avatarNode: itemNode.avatarNode)
|
StoryContainerScreen.openArchivedStories(context: self.context, parentController: self, avatarNode: itemNode.avatarNode)
|
||||||
case let .peer(peerId):
|
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 emojiSearchCategories: Int8 = 25
|
||||||
public static let cachedEmojiQueryResults: Int8 = 26
|
public static let cachedEmojiQueryResults: Int8 = 26
|
||||||
public static let cachedPeerStoryListHeads: Int8 = 27
|
public static let cachedPeerStoryListHeads: Int8 = 27
|
||||||
|
public static let displayedStoryNotifications: Int8 = 28
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct UnorderedItemList {
|
public struct UnorderedItemList {
|
||||||
|
@ -2061,3 +2061,17 @@ func _internal_enableStoryStealthMode(account: Account) -> Signal<Never, NoError
|
|||||||
|> ignoreValues
|
|> 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)
|
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(
|
return openPeerStoriesCustom(
|
||||||
context: context,
|
context: context,
|
||||||
peerId: peerId,
|
peerId: peerId,
|
||||||
@ -149,7 +149,7 @@ public extension StoryContainerScreen {
|
|||||||
guard let avatarNode else {
|
guard let avatarNode else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let _ = avatarNode.pushLoadingStatus(signal: signal)
|
sharedProgressDisposable?.set(avatarNode.pushLoadingStatus(signal: signal))
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2434,6 +2434,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
soundImage = "Stories/SoundOn"
|
soundImage = "Stories/SoundOn"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO:anim_storymute
|
||||||
let soundButtonSize = self.soundButton.update(
|
let soundButtonSize = self.soundButton.update(
|
||||||
transition: transition,
|
transition: transition,
|
||||||
component: AnyComponent(PlainButtonComponent(
|
component: AnyComponent(PlainButtonComponent(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user