diff --git a/TelegramUI/ChatController.swift b/TelegramUI/ChatController.swift index 0389ef5d9a..8492e0f91d 100644 --- a/TelegramUI/ChatController.swift +++ b/TelegramUI/ChatController.swift @@ -1491,102 +1491,111 @@ public final class ChatController: TelegramController, KeyShortcutResponder, UID self.chatDisplayNode.peerView = self.peerView let initialData = self.chatDisplayNode.historyNode.initialData - |> take(1) - |> beforeNext { [weak self] combinedInitialData in - if let strongSelf = self, let combinedInitialData = combinedInitialData { - if let interfaceState = combinedInitialData.initialData?.chatInterfaceState as? ChatInterfaceState { - var pinnedMessageId: MessageId? - var peerIsBlocked: Bool = false - var canReport: Bool = false - var callsAvailable: Bool = true - var callsPrivate: Bool = false - if let cachedData = combinedInitialData.cachedData as? CachedChannelData { - pinnedMessageId = cachedData.pinnedMessageId - canReport = cachedData.reportStatus == .canReport - } else if let cachedData = combinedInitialData.cachedData as? CachedUserData { - peerIsBlocked = cachedData.isBlocked - canReport = cachedData.reportStatus == .canReport - callsAvailable = cachedData.callsAvailable - callsPrivate = cachedData.callsPrivate - pinnedMessageId = cachedData.pinnedMessageId - } else if let cachedData = combinedInitialData.cachedData as? CachedGroupData { - canReport = cachedData.reportStatus == .canReport - pinnedMessageId = cachedData.pinnedMessageId - } else if let cachedData = combinedInitialData.cachedData as? CachedSecretChatData { - canReport = cachedData.reportStatus == .canReport - } - var pinnedMessage: Message? - if let pinnedMessageId = pinnedMessageId { - if let cachedDataMessages = combinedInitialData.cachedDataMessages { - pinnedMessage = cachedDataMessages[pinnedMessageId] - } - } - strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: false, { updated in - var updated = updated - - updated = updated.updatedInterfaceState({ _ in return interfaceState }) - - updated = updated.updatedKeyboardButtonsMessage(combinedInitialData.buttonKeyboardMessage) - updated = updated.updatedPinnedMessageId(pinnedMessageId) - updated = updated.updatedPinnedMessage(pinnedMessage) - updated = updated.updatedPeerIsBlocked(peerIsBlocked) - updated = updated.updatedCanReportPeer(canReport) - updated = updated.updatedCallsAvailable(callsAvailable) - updated = updated.updatedCallsPrivate(callsPrivate) - updated = updated.updatedTitlePanelContext({ context in - if pinnedMessageId != nil { - if !context.contains(where: { - switch $0 { - case .pinnedMessage: - return true - default: - return false - } - }) { - var updatedContexts = context - updatedContexts.append(.pinnedMessage) - return updatedContexts.sorted() - } else { - return context - } - } else { - if let index = context.index(where: { - switch $0 { - case .pinnedMessage: - return true - default: - return false - } - }) { - var updatedContexts = context - updatedContexts.remove(at: index) - return updatedContexts - } else { - return context - } - } - }) - if let editMessage = interfaceState.editMessage, let message = combinedInitialData.initialData?.associatedMessages[editMessage.messageId] { - updated = updatedChatEditInterfaceMessagetState(state: updated, message: message) - } - return updated - }) + |> take(1) + |> beforeNext { [weak self] combinedInitialData in + guard let strongSelf = self, let combinedInitialData = combinedInitialData else { + return + } + if let interfaceState = combinedInitialData.initialData?.chatInterfaceState as? ChatInterfaceState { + var pinnedMessageId: MessageId? + var peerIsBlocked: Bool = false + var canReport: Bool = false + var callsAvailable: Bool = true + var callsPrivate: Bool = false + if let cachedData = combinedInitialData.cachedData as? CachedChannelData { + pinnedMessageId = cachedData.pinnedMessageId + canReport = cachedData.reportStatus == .canReport + } else if let cachedData = combinedInitialData.cachedData as? CachedUserData { + peerIsBlocked = cachedData.isBlocked + canReport = cachedData.reportStatus == .canReport + callsAvailable = cachedData.callsAvailable + callsPrivate = cachedData.callsPrivate + pinnedMessageId = cachedData.pinnedMessageId + } else if let cachedData = combinedInitialData.cachedData as? CachedGroupData { + canReport = cachedData.reportStatus == .canReport + pinnedMessageId = cachedData.pinnedMessageId + } else if let cachedData = combinedInitialData.cachedData as? CachedSecretChatData { + canReport = cachedData.reportStatus == .canReport + } + var pinnedMessage: Message? + if let pinnedMessageId = pinnedMessageId { + if let cachedDataMessages = combinedInitialData.cachedDataMessages { + pinnedMessage = cachedDataMessages[pinnedMessageId] } - if let readStateData = combinedInitialData.readStateData { - if case let .peer(peerId) = strongSelf.chatLocation, let peerReadStateData = readStateData[peerId], let notificationSettings = peerReadStateData.notificationSettings { - var globalRemainingUnreadChatCount = peerReadStateData.totalUnreadChatCount - if !notificationSettings.isRemovedFromTotalUnreadCount && peerReadStateData.unreadCount > 0 { - globalRemainingUnreadChatCount -= 1 - } - if globalRemainingUnreadChatCount > 0 { - strongSelf.navigationItem.badge = "\(globalRemainingUnreadChatCount)" + } + strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: false, { updated in + var updated = updated + + updated = updated.updatedInterfaceState({ _ in return interfaceState }) + + updated = updated.updatedKeyboardButtonsMessage(combinedInitialData.buttonKeyboardMessage) + updated = updated.updatedPinnedMessageId(pinnedMessageId) + updated = updated.updatedPinnedMessage(pinnedMessage) + updated = updated.updatedPeerIsBlocked(peerIsBlocked) + updated = updated.updatedCanReportPeer(canReport) + updated = updated.updatedCallsAvailable(callsAvailable) + updated = updated.updatedCallsPrivate(callsPrivate) + updated = updated.updatedTitlePanelContext({ context in + if pinnedMessageId != nil { + if !context.contains(where: { + switch $0 { + case .pinnedMessage: + return true + default: + return false + } + }) { + var updatedContexts = context + updatedContexts.append(.pinnedMessage) + return updatedContexts.sorted() } else { - strongSelf.navigationItem.badge = "" + return context + } + } else { + if let index = context.index(where: { + switch $0 { + case .pinnedMessage: + return true + default: + return false + } + }) { + var updatedContexts = context + updatedContexts.remove(at: index) + return updatedContexts + } else { + return context } } + }) + if let editMessage = interfaceState.editMessage, let message = combinedInitialData.initialData?.associatedMessages[editMessage.messageId] { + updated = updatedChatEditInterfaceMessagetState(state: updated, message: message) + } + return updated + }) + } + if let readStateData = combinedInitialData.readStateData { + if case let .peer(peerId) = strongSelf.chatLocation, let peerReadStateData = readStateData[peerId], let notificationSettings = peerReadStateData.notificationSettings { + + let inAppSettings = peerReadStateData.inAppNotificationSettings ?? InAppNotificationSettings.defaultSettings + let (count, _) = renderedTotalUnreadCount(inAppSettings: inAppSettings, totalUnreadState: peerReadStateData.totalState ?? ChatListTotalUnreadState(absoluteCounters: [:], filteredCounters: [:])) + + var globalRemainingUnreadChatCount = count + if !notificationSettings.isRemovedFromTotalUnreadCount && peerReadStateData.unreadCount > 0 { + if case .messages = inAppSettings.totalUnreadCountDisplayCategory { + globalRemainingUnreadChatCount -= peerReadStateData.unreadCount + } else { + globalRemainingUnreadChatCount -= 1 + } + } + if globalRemainingUnreadChatCount > 0 { + strongSelf.navigationItem.badge = "\(globalRemainingUnreadChatCount)" + } else { + strongSelf.navigationItem.badge = "" } } } + } self.buttonKeyboardMessageDisposable = self.chatDisplayNode.historyNode.buttonKeyboardMessage.start(next: { [weak self] message in if let strongSelf = self { @@ -2696,12 +2705,14 @@ public final class ChatController: TelegramController, KeyShortcutResponder, UID var unreadCount: Int32 = 0 var totalChatCount: Int32 = 0 + var inAppSettingsValue: InAppNotificationSettings? if let view = views.views[unreadCountsKey] as? UnreadMessageCountsView { if let count = view.count(for: .peer(peerId)) { unreadCount = count } if let (preferencesEntry, state) = view.total() { let inAppSettings = (preferencesEntry as? InAppNotificationSettings) ?? InAppNotificationSettings.defaultSettings + inAppSettingsValue = inAppSettings let (count, _) = renderedTotalUnreadCount(inAppSettings: inAppSettings, totalUnreadState: state) totalChatCount = count } @@ -2712,7 +2723,12 @@ public final class ChatController: TelegramController, KeyShortcutResponder, UID if let view = views.views[notificationSettingsKey] as? PeerNotificationSettingsView, let notificationSettings = view.notificationSettings[peerId] { var globalRemainingUnreadChatCount = totalChatCount if !notificationSettings.isRemovedFromTotalUnreadCount && unreadCount > 0 { - globalRemainingUnreadChatCount -= 1 + let inAppSettings = inAppSettingsValue ?? InAppNotificationSettings.defaultSettings + if case .messages = inAppSettings.totalUnreadCountDisplayCategory { + globalRemainingUnreadChatCount -= unreadCount + } else { + globalRemainingUnreadChatCount -= 1 + } } if globalRemainingUnreadChatCount > 0 { diff --git a/TelegramUI/ChatHistoryListNode.swift b/TelegramUI/ChatHistoryListNode.swift index b581b48439..97f2afce73 100644 --- a/TelegramUI/ChatHistoryListNode.swift +++ b/TelegramUI/ChatHistoryListNode.swift @@ -42,7 +42,8 @@ enum ChatHistoryViewUpdateType { public struct ChatHistoryCombinedInitialReadStateData { public let unreadCount: Int32 - public let totalUnreadChatCount: Int32 + public let totalState: ChatListTotalUnreadState? + public let inAppNotificationSettings: InAppNotificationSettings? public let notificationSettings: PeerNotificationSettings? } @@ -394,6 +395,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { additionalData.append(.cachedPeerData(peerId)) additionalData.append(.cachedPeerDataMessages(peerId)) additionalData.append(.peerNotificationSettings(peerId)) + additionalData.append(.preferencesEntry(ApplicationSpecificPreferencesKeys.inAppNotificationSettings)) if peerId.namespace == Namespaces.Peer.CloudChannel { additionalData.append(.cacheEntry(cachedChannelAdminIdsEntryId(peerId: peerId))) additionalData.append(.peer(peerId)) diff --git a/TelegramUI/ChatHistoryViewForLocation.swift b/TelegramUI/ChatHistoryViewForLocation.swift index 3d83fa7c1c..c9e8c1bd09 100644 --- a/TelegramUI/ChatHistoryViewForLocation.swift +++ b/TelegramUI/ChatHistoryViewForLocation.swift @@ -15,7 +15,8 @@ func chatHistoryViewForLocation(_ location: ChatHistoryLocation, account: Accoun } else { signal = account.viewTracker.aroundMessageOfInterestHistoryViewForLocation(chatLocation, count: count, tagMask: tagMask, orderStatistics: orderStatistics, additionalData: additionalData) } - return signal |> map { view, updateType, initialData -> ChatHistoryViewUpdate in + return signal + |> map { view, updateType, initialData -> ChatHistoryViewUpdate in let (cachedData, cachedDataMessages, readStateData) = extractAdditionalData(view: view, chatLocation: chatLocation) let combinedInitialData = ChatHistoryCombinedInitialData(initialData: initialData, buttonKeyboardMessage: view.topTaggedMessages.first, cachedData: cachedData, cachedDataMessages: cachedDataMessages, readStateData: readStateData) @@ -172,12 +173,16 @@ private func extractAdditionalData(view: MessageHistoryView, chatLocation: ChatL var cachedDataMessages: [MessageId: Message]? var readStateData: [PeerId: ChatHistoryCombinedInitialReadStateData] = [:] var notificationSettings: PeerNotificationSettings? + var inAppNotificationSettings: InAppNotificationSettings? loop: for data in view.additionalData { switch data { case let .peerNotificationSettings(value): notificationSettings = value - break loop + case let .preferencesEntry(key, value): + if key == ApplicationSpecificPreferencesKeys.inAppNotificationSettings { + inAppNotificationSettings = value as? InAppNotificationSettings + } default: break } @@ -200,7 +205,7 @@ private func extractAdditionalData(view: MessageHistoryView, chatLocation: ChatL case let .peer(peerId): if let combinedReadStates = view.fixedReadStates { if case let .peer(readStates) = combinedReadStates, let readState = readStates[peerId] { - readStateData[peerId] = ChatHistoryCombinedInitialReadStateData(unreadCount: readState.count, totalUnreadChatCount: totalUnreadState.count(for: .filtered, in: .chats, with: [.regularChatsAndPrivateGroups]), notificationSettings: notificationSettings) + readStateData[peerId] = ChatHistoryCombinedInitialReadStateData(unreadCount: readState.count, totalState: totalUnreadState, inAppNotificationSettings: inAppNotificationSettings, notificationSettings: notificationSettings) } } case .group: diff --git a/TelegramUI/GalleryController.swift b/TelegramUI/GalleryController.swift index 9dd78f77c1..b6d94eff90 100644 --- a/TelegramUI/GalleryController.swift +++ b/TelegramUI/GalleryController.swift @@ -132,10 +132,10 @@ func galleryItemForEntry(account: Account, presentationData: PresentationData, e if file.isVideo { let content: UniversalVideoContent if file.isAnimated { - content = NativeVideoContent(id: .message(message.id, message.stableId + 1, file.fileId), fileReference: .message(message: MessageReference(message), media: file), streamVideo: true, loopVideo: true, enableSound: false) + content = NativeVideoContent(id: .message(message.id, message.stableId + 1, file.fileId), fileReference: .message(message: MessageReference(message), media: file), streamVideo: false, loopVideo: true, enableSound: false) } else { if true || (file.mimeType == "video/mpeg4" || file.mimeType == "video/mov" || file.mimeType == "video/mp4") { - content = NativeVideoContent(id: .message(message.id, message.stableId, file.fileId), fileReference: .message(message: MessageReference(message), media: file), streamVideo: streamVideos, loopVideo: loopVideos) + content = NativeVideoContent(id: .message(message.id, message.stableId, file.fileId), fileReference: .message(message: MessageReference(message), media: file), streamVideo: true, loopVideo: loopVideos) } else { content = PlatformVideoContent(id: .message(message.id, message.stableId, file.fileId), fileReference: .message(message: MessageReference(message), media: file), streamVideo: streamVideos, loopVideo: loopVideos) } diff --git a/TelegramUI/UniversalVideoGalleryItem.swift b/TelegramUI/UniversalVideoGalleryItem.swift index 04cefb193f..8996243f30 100644 --- a/TelegramUI/UniversalVideoGalleryItem.swift +++ b/TelegramUI/UniversalVideoGalleryItem.swift @@ -340,7 +340,8 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { } } - self.statusDisposable.set((combineLatest(videoNode.status, mediaFileStatus) |> deliverOnMainQueue).start(next: { [weak self] value, fetchStatus in + self.statusDisposable.set((combineLatest(videoNode.status, mediaFileStatus) + |> deliverOnMainQueue).start(next: { [weak self] value, fetchStatus in if let strongSelf = self { var initialBuffering = false var buffering = false