diff --git a/submodules/ChatListFilterSettingsHeaderItem/BUCK b/submodules/ChatListFilterSettingsHeaderItem/BUCK new file mode 100644 index 0000000000..de34d12381 --- /dev/null +++ b/submodules/ChatListFilterSettingsHeaderItem/BUCK @@ -0,0 +1,22 @@ +load("//Config:buck_rule_macros.bzl", "static_library") + +static_library( + name = "ChatListFilterSettingsHeaderItem", + srcs = glob([ + "Sources/**/*.swift", + ]), + deps = [ + "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit#shared", + "//submodules/AsyncDisplayKit:AsyncDisplayKit#shared", + "//submodules/Display:Display#shared", + "//submodules/TelegramPresentationData:TelegramPresentationData", + "//submodules/ItemListUI:ItemListUI", + "//submodules/PresentationDataUtils:PresentationDataUtils", + "//submodules/AnimatedStickerNode:AnimatedStickerNode", + "//submodules/AppBundle:AppBundle", + ], + frameworks = [ + "$SDKROOT/System/Library/Frameworks/Foundation.framework", + "$SDKROOT/System/Library/Frameworks/UIKit.framework", + ], +) diff --git a/submodules/ChatListFilterSettingsHeaderItem/BUILD b/submodules/ChatListFilterSettingsHeaderItem/BUILD new file mode 100644 index 0000000000..d3d38bff2d --- /dev/null +++ b/submodules/ChatListFilterSettingsHeaderItem/BUILD @@ -0,0 +1,22 @@ +load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library") + +swift_library( + name = "ChatListFilterSettingsHeaderItem", + module_name = "ChatListFilterSettingsHeaderItem", + srcs = glob([ + "Sources/**/*.swift", + ]), + deps = [ + "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", + "//submodules/AsyncDisplayKit:AsyncDisplayKit", + "//submodules/Display:Display", + "//submodules/TelegramPresentationData:TelegramPresentationData", + "//submodules/ItemListUI:ItemListUI", + "//submodules/PresentationDataUtils:PresentationDataUtils", + "//submodules/AnimatedStickerNode:AnimatedStickerNode", + "//submodules/AppBundle:AppBundle", + ], + visibility = [ + "//visibility:public", + ], +) diff --git a/submodules/ChatListUI/Sources/ChatListFilterSettingsHeaderItem.swift b/submodules/ChatListFilterSettingsHeaderItem/Sources/ChatListFilterSettingsHeaderItem.swift similarity index 84% rename from submodules/ChatListUI/Sources/ChatListFilterSettingsHeaderItem.swift rename to submodules/ChatListFilterSettingsHeaderItem/Sources/ChatListFilterSettingsHeaderItem.swift index d322c174fa..f084cfa88d 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterSettingsHeaderItem.swift +++ b/submodules/ChatListFilterSettingsHeaderItem/Sources/ChatListFilterSettingsHeaderItem.swift @@ -9,25 +9,26 @@ import PresentationDataUtils import AnimatedStickerNode import AppBundle -enum ChatListFilterSettingsHeaderAnimation { +public enum ChatListFilterSettingsHeaderAnimation { case folders case newFolder + case discussionGroupSetup } -class ChatListFilterSettingsHeaderItem: ListViewItem, ItemListItem { +public class ChatListFilterSettingsHeaderItem: ListViewItem, ItemListItem { let theme: PresentationTheme let text: String let animation: ChatListFilterSettingsHeaderAnimation - let sectionId: ItemListSectionId + public let sectionId: ItemListSectionId - init(theme: PresentationTheme, text: String, animation: ChatListFilterSettingsHeaderAnimation, sectionId: ItemListSectionId) { + public init(theme: PresentationTheme, text: String, animation: ChatListFilterSettingsHeaderAnimation, sectionId: ItemListSectionId) { self.theme = theme self.text = text self.animation = animation self.sectionId = sectionId } - func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { + public func nodeConfiguredForParams(async: @escaping (@escaping () -> Void) -> Void, params: ListViewItemLayoutParams, synchronousLoads: Bool, previousItem: ListViewItem?, nextItem: ListViewItem?, completion: @escaping (ListViewItemNode, @escaping () -> (Signal?, (ListViewItemApply) -> Void)) -> Void) { async { let node = ChatListFilterSettingsHeaderItemNode() let (layout, apply) = node.asyncLayout()(self, params, itemListNeighbors(item: self, topItem: previousItem as? ItemListItem, bottomItem: nextItem as? ItemListItem)) @@ -43,7 +44,7 @@ class ChatListFilterSettingsHeaderItem: ListViewItem, ItemListItem { } } - func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { + public func updateNode(async: @escaping (@escaping () -> Void) -> Void, node: @escaping () -> ListViewItemNode, params: ListViewItemLayoutParams, previousItem: ListViewItem?, nextItem: ListViewItem?, animation: ListViewItemUpdateAnimation, completion: @escaping (ListViewItemNodeLayout, @escaping (ListViewItemApply) -> Void) -> Void) { Queue.mainQueue().async { guard let nodeValue = node() as? ChatListFilterSettingsHeaderItemNode else { assertionFailure() @@ -124,6 +125,8 @@ class ChatListFilterSettingsHeaderItemNode: ListViewItemNode { animationName = "ChatListFolders" case .newFolder: animationName = "ChatListNewFolder" + case .discussionGroupSetup: + animationName = "DiscussionGroupSetup" } if let path = getAppBundle().path(forResource: animationName, ofType: "tgs") { strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 192, height: 192, playbackMode: .once, mode: .direct(cachePathPrefix: nil)) diff --git a/submodules/ChatListUI/BUCK b/submodules/ChatListUI/BUCK index 3a99a42a00..84d1f8d7f1 100644 --- a/submodules/ChatListUI/BUCK +++ b/submodules/ChatListUI/BUCK @@ -55,6 +55,7 @@ static_library( "//submodules/ListSectionHeaderNode:ListSectionHeaderNode", "//submodules/ChatInterfaceState:ChatInterfaceState", "//submodules/GridMessageSelectionNode:GridMessageSelectionNode", + "//submodules/ChatListFilterSettingsHeaderItem:ChatListFilterSettingsHeaderItem", ], frameworks = [ "$SDKROOT/System/Library/Frameworks/Foundation.framework", diff --git a/submodules/ChatListUI/BUILD b/submodules/ChatListUI/BUILD index e0756763e3..726dfe65d9 100644 --- a/submodules/ChatListUI/BUILD +++ b/submodules/ChatListUI/BUILD @@ -55,6 +55,7 @@ swift_library( "//submodules/ChatInterfaceState:ChatInterfaceState", "//submodules/ShareController:ShareController", "//submodules/GridMessageSelectionNode:GridMessageSelectionNode", + "//submodules/ChatListFilterSettingsHeaderItem:ChatListFilterSettingsHeaderItem", ], visibility = [ "//visibility:public", diff --git a/submodules/ChatListUI/Sources/ChatListFilterPresetController.swift b/submodules/ChatListUI/Sources/ChatListFilterPresetController.swift index 604402f7b7..7925b415d6 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterPresetController.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterPresetController.swift @@ -13,6 +13,7 @@ import TelegramUIPreferences import ItemListPeerItem import ItemListPeerActionItem import AvatarNode +import ChatListFilterSettingsHeaderItem private enum FilterSection: Int32, Hashable { case include diff --git a/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift b/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift index e75d1ef7cc..5dab90058b 100644 --- a/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift +++ b/submodules/ChatListUI/Sources/ChatListFilterPresetListController.swift @@ -10,6 +10,7 @@ import TelegramUIPreferences import ItemListUI import AccountContext import ItemListPeerActionItem +import ChatListFilterSettingsHeaderItem private final class ChatListFilterPresetListControllerArguments { let context: AccountContext diff --git a/submodules/ContextUI/Sources/ContextController.swift b/submodules/ContextUI/Sources/ContextController.swift index 542ebd76ca..3c21edd6b1 100644 --- a/submodules/ContextUI/Sources/ContextController.swift +++ b/submodules/ContextUI/Sources/ContextController.swift @@ -555,7 +555,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi let propertyAnimator = propertyAnimator as? UIViewPropertyAnimator propertyAnimator?.stopAnimation(true) } - self.effectView.effect = makeCustomZoomBlurEffect() + self.effectView.effect = makeCustomZoomBlurEffect(isLight: !self.presentationData.theme.overallDarkAppearance) self.effectView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2 * animationDurationFactor) self.propertyAnimator = UIViewPropertyAnimator(duration: 0.2 * animationDurationFactor * UIView.animationDurationFactor(), curve: .easeInOut, animations: { }) @@ -573,7 +573,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi } } else { UIView.animate(withDuration: 0.2 * animationDurationFactor, animations: { - self.effectView.effect = makeCustomZoomBlurEffect() + self.effectView.effect = makeCustomZoomBlurEffect(isLight: !self.presentationData.theme.overallDarkAppearance) }, completion: { [weak self] _ in self?.didCompleteAnimationIn = true self?.actionsContainerNode.animateIn() @@ -1082,7 +1082,7 @@ private final class ContextControllerNode: ViewControllerTracingNode, UIScrollVi propertyAnimator?.stopAnimation(true) } } - self.effectView.effect = makeCustomZoomBlurEffect() + self.effectView.effect = makeCustomZoomBlurEffect(isLight: !self.presentationData.theme.overallDarkAppearance) self.dimNode.alpha = 1.0 } self.dimNode.isHidden = false diff --git a/submodules/Display/Source/UIKitUtils.swift b/submodules/Display/Source/UIKitUtils.swift index b4dc3d327d..123691766e 100644 --- a/submodules/Display/Source/UIKitUtils.swift +++ b/submodules/Display/Source/UIKitUtils.swift @@ -19,8 +19,8 @@ public func springAnimationValueAt(_ animation: CABasicAnimation, _ t: CGFloat) return springAnimationValueAtImpl(animation, t) } -public func makeCustomZoomBlurEffect() -> UIBlurEffect? { - return makeCustomZoomBlurEffectImpl() +public func makeCustomZoomBlurEffect(isLight: Bool) -> UIBlurEffect? { + return makeCustomZoomBlurEffectImpl(isLight) } public func applySmoothRoundedCorners(_ layer: CALayer) { diff --git a/submodules/PeerInfoUI/BUCK b/submodules/PeerInfoUI/BUCK index 16d723277d..1372054787 100644 --- a/submodules/PeerInfoUI/BUCK +++ b/submodules/PeerInfoUI/BUCK @@ -65,6 +65,7 @@ static_library( "//submodules/SolidRoundedButtonNode:SolidRoundedButtonNode", "//submodules/ChatListSearchItemHeader:ChatListSearchItemHeader", "//submodules/StatisticsUI:StatisticsUI", + "//submodules/ChatListFilterSettingsHeaderItem:ChatListFilterSettingsHeaderItem", ], frameworks = [ "$SDKROOT/System/Library/Frameworks/Foundation.framework", diff --git a/submodules/PeerInfoUI/BUILD b/submodules/PeerInfoUI/BUILD index b5c142ca04..b8bdb1454d 100644 --- a/submodules/PeerInfoUI/BUILD +++ b/submodules/PeerInfoUI/BUILD @@ -66,6 +66,7 @@ swift_library( "//submodules/SolidRoundedButtonNode:SolidRoundedButtonNode", "//submodules/ChatListSearchItemHeader:ChatListSearchItemHeader", "//submodules/StatisticsUI:StatisticsUI", + "//submodules/ChatListFilterSettingsHeaderItem:ChatListFilterSettingsHeaderItem", ], visibility = [ "//visibility:public", diff --git a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift index 93e5dbdf56..c47cc218fb 100644 --- a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift @@ -15,6 +15,7 @@ import AlertUI import PresentationDataUtils import ItemListPeerItem import ItemListPeerActionItem +import ChatListFilterSettingsHeaderItem private final class ChannelDiscussionGroupSetupControllerArguments { let context: AccountContext @@ -131,8 +132,18 @@ private enum ChannelDiscussionGroupSetupControllerEntry: ItemListNodeEntry { func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { let arguments = arguments as! ChannelDiscussionGroupSetupControllerArguments switch self { - case let .header(theme, strings, title, isGroup, label): - return ChannelDiscussionGroupSetupHeaderItem(theme: theme, strings: strings, title: title, isGroup: isGroup, label: label, sectionId: self.section) + case let .header(_, _, title, isGroup, _): + let text: String + if let title = title { + if isGroup { + text = presentationData.strings.Channel_DiscussionGroup_HeaderGroupSet(title).0 + } else { + text = presentationData.strings.Channel_DiscussionGroup_HeaderSet(title).0 + } + } else { + text = "" + } + return ChatListFilterSettingsHeaderItem(theme: presentationData.theme, text: text, animation: .discussionGroupSetup, sectionId: self.section) case let .create(theme, text): return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.plusIconImage(theme), title: text, sectionId: self.section, editing: false, action: { arguments.createGroup() diff --git a/submodules/SettingsUI/Sources/TabBarAccountSwitchControllerNode.swift b/submodules/SettingsUI/Sources/TabBarAccountSwitchControllerNode.swift index ca1c14f2dd..0c509ba19a 100644 --- a/submodules/SettingsUI/Sources/TabBarAccountSwitchControllerNode.swift +++ b/submodules/SettingsUI/Sources/TabBarAccountSwitchControllerNode.swift @@ -306,7 +306,10 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode { propertyAnimator?.stopAnimation(true) } self.propertyAnimator = UIViewPropertyAnimator(duration: 0.2 * animationDurationFactor, curve: .easeInOut, animations: { [weak self] in - self?.effectView.effect = makeCustomZoomBlurEffect() + guard let strongSelf = self else { + return + } + strongSelf.effectView.effect = makeCustomZoomBlurEffect(isLight: !strongSelf.presentationData.theme.overallDarkAppearance) }) } @@ -319,7 +322,7 @@ final class TabBarAccountSwitchControllerNode: ViewControllerTracingNode { } } else { UIView.animate(withDuration: 0.2 * animationDurationFactor, animations: { - self.effectView.effect = makeCustomZoomBlurEffect() + self.effectView.effect = makeCustomZoomBlurEffect(isLight: !self.presentationData.theme.overallDarkAppearance) }, completion: { _ in }) } diff --git a/submodules/TelegramApi/Sources/Api0.swift b/submodules/TelegramApi/Sources/Api0.swift index afe284a3c4..abba697b71 100644 --- a/submodules/TelegramApi/Sources/Api0.swift +++ b/submodules/TelegramApi/Sources/Api0.swift @@ -255,7 +255,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = { dict[643940105] = { return Api.Update.parse_updatePhoneCallSignalingData($0) } dict[1708307556] = { return Api.Update.parse_updateChannelParticipant($0) } dict[1854571743] = { return Api.Update.parse_updateChannelMessageForwards($0) } - dict[-966672061] = { return Api.Update.parse_updateReadChannelDiscussionInbox($0) } + dict[482860628] = { return Api.Update.parse_updateReadChannelDiscussionInbox($0) } dict[1178116716] = { return Api.Update.parse_updateReadChannelDiscussionOutbox($0) } dict[610945826] = { return Api.Update.parse_updatePeerBlocked($0) } dict[-13975905] = { return Api.Update.parse_updateChannelUserTyping($0) } diff --git a/submodules/TelegramApi/Sources/Api1.swift b/submodules/TelegramApi/Sources/Api1.swift index 544fed00d9..ffad42a048 100644 --- a/submodules/TelegramApi/Sources/Api1.swift +++ b/submodules/TelegramApi/Sources/Api1.swift @@ -6236,7 +6236,7 @@ public extension Api { case updatePhoneCallSignalingData(phoneCallId: Int64, data: Buffer) case updateChannelParticipant(flags: Int32, channelId: Int32, date: Int32, userId: Int32, prevParticipant: Api.ChannelParticipant?, newParticipant: Api.ChannelParticipant?, qts: Int32) case updateChannelMessageForwards(channelId: Int32, id: Int32, forwards: Int32) - case updateReadChannelDiscussionInbox(channelId: Int32, topMsgId: Int32, readMaxId: Int32) + case updateReadChannelDiscussionInbox(flags: Int32, channelId: Int32, topMsgId: Int32, readMaxId: Int32, broadcastId: Int32?, broadcastPost: Int32?) case updateReadChannelDiscussionOutbox(channelId: Int32, topMsgId: Int32, readMaxId: Int32) case updatePeerBlocked(peerId: Api.Peer, blocked: Api.Bool) case updateChannelUserTyping(flags: Int32, channelId: Int32, topMsgId: Int32?, userId: Int32, action: Api.SendMessageAction) @@ -6934,13 +6934,16 @@ public extension Api { serializeInt32(id, buffer: buffer, boxed: false) serializeInt32(forwards, buffer: buffer, boxed: false) break - case .updateReadChannelDiscussionInbox(let channelId, let topMsgId, let readMaxId): + case .updateReadChannelDiscussionInbox(let flags, let channelId, let topMsgId, let readMaxId, let broadcastId, let broadcastPost): if boxed { - buffer.appendInt32(-966672061) + buffer.appendInt32(482860628) } + serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(channelId, buffer: buffer, boxed: false) serializeInt32(topMsgId, buffer: buffer, boxed: false) serializeInt32(readMaxId, buffer: buffer, boxed: false) + if Int(flags) & Int(1 << 0) != 0 {serializeInt32(broadcastId!, buffer: buffer, boxed: false)} + if Int(flags) & Int(1 << 0) != 0 {serializeInt32(broadcastPost!, buffer: buffer, boxed: false)} break case .updateReadChannelDiscussionOutbox(let channelId, let topMsgId, let readMaxId): if boxed { @@ -7144,8 +7147,8 @@ public extension Api { return ("updateChannelParticipant", [("flags", flags), ("channelId", channelId), ("date", date), ("userId", userId), ("prevParticipant", prevParticipant), ("newParticipant", newParticipant), ("qts", qts)]) case .updateChannelMessageForwards(let channelId, let id, let forwards): return ("updateChannelMessageForwards", [("channelId", channelId), ("id", id), ("forwards", forwards)]) - case .updateReadChannelDiscussionInbox(let channelId, let topMsgId, let readMaxId): - return ("updateReadChannelDiscussionInbox", [("channelId", channelId), ("topMsgId", topMsgId), ("readMaxId", readMaxId)]) + case .updateReadChannelDiscussionInbox(let flags, let channelId, let topMsgId, let readMaxId, let broadcastId, let broadcastPost): + return ("updateReadChannelDiscussionInbox", [("flags", flags), ("channelId", channelId), ("topMsgId", topMsgId), ("readMaxId", readMaxId), ("broadcastId", broadcastId), ("broadcastPost", broadcastPost)]) case .updateReadChannelDiscussionOutbox(let channelId, let topMsgId, let readMaxId): return ("updateReadChannelDiscussionOutbox", [("channelId", channelId), ("topMsgId", topMsgId), ("readMaxId", readMaxId)]) case .updatePeerBlocked(let peerId, let blocked): @@ -8540,11 +8543,20 @@ public extension Api { _2 = reader.readInt32() var _3: Int32? _3 = reader.readInt32() + var _4: Int32? + _4 = reader.readInt32() + var _5: Int32? + if Int(_1!) & Int(1 << 0) != 0 {_5 = reader.readInt32() } + var _6: Int32? + if Int(_1!) & Int(1 << 0) != 0 {_6 = reader.readInt32() } let _c1 = _1 != nil let _c2 = _2 != nil let _c3 = _3 != nil - if _c1 && _c2 && _c3 { - return Api.Update.updateReadChannelDiscussionInbox(channelId: _1!, topMsgId: _2!, readMaxId: _3!) + let _c4 = _4 != nil + let _c5 = (Int(_1!) & Int(1 << 0) == 0) || _5 != nil + let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil + if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 { + return Api.Update.updateReadChannelDiscussionInbox(flags: _1!, channelId: _2!, topMsgId: _3!, readMaxId: _4!, broadcastId: _5, broadcastPost: _6) } else { return nil diff --git a/submodules/TelegramCore/Sources/AccountIntermediateState.swift b/submodules/TelegramCore/Sources/AccountIntermediateState.swift index 10371f4d08..780b8c75c9 100644 --- a/submodules/TelegramCore/Sources/AccountIntermediateState.swift +++ b/submodules/TelegramCore/Sources/AccountIntermediateState.swift @@ -108,7 +108,7 @@ enum AccountStateMutationOperation { case SyncChatListFilters case UpdateChatListFilterOrder(order: [Int32]) case UpdateChatListFilter(id: Int32, filter: Api.DialogFilter?) - case UpdateReadThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool) + case UpdateReadThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool, mainChannelMessage: MessageId?) } struct HoleFromPreviousState { @@ -271,8 +271,8 @@ struct AccountMutableState { self.addOperation(.ReadOutbox(messageId, timestamp)) } - mutating func readThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool) { - self.addOperation(.UpdateReadThread(threadMessageId: threadMessageId, readMaxId: readMaxId, isIncoming: isIncoming)) + mutating func readThread(threadMessageId: MessageId, readMaxId: Int32, isIncoming: Bool, mainChannelMessage: MessageId?) { + self.addOperation(.UpdateReadThread(threadMessageId: threadMessageId, readMaxId: readMaxId, isIncoming: isIncoming, mainChannelMessage: mainChannelMessage)) } mutating func readGroupFeedInbox(groupId: PeerGroupId, index: MessageIndex) { diff --git a/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift index 8435dc8ccb..3b2a39acb2 100644 --- a/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift @@ -989,6 +989,14 @@ private func finalStateWithUpdatesAndServerTime(postbox: Postbox, network: Netwo updatedState.resetIncomingReadState(groupId: PeerGroupId(rawValue: folderId ?? 0), peerId: peer.peerId, namespace: Namespaces.Message.Cloud, maxIncomingReadId: maxId, count: stillUnreadCount, pts: pts) case let .updateReadHistoryOutbox(peer, maxId, _, _): updatedState.readOutbox(MessageId(peerId: peer.peerId, namespace: Namespaces.Message.Cloud, id: maxId), timestamp: updatesDate) + case let .updateReadChannelDiscussionInbox(_, channelId, topMsgId, readMaxId, mainChannelId, mainChannelPost): + var mainChannelMessage: MessageId? + if let mainChannelId = mainChannelId, let mainChannelPost = mainChannelPost { + mainChannelMessage = MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: mainChannelId), namespace: Namespaces.Message.Cloud, id: mainChannelPost) + } + updatedState.readThread(threadMessageId: MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: topMsgId), readMaxId: readMaxId, isIncoming: true, mainChannelMessage: mainChannelMessage) + case let .updateReadChannelDiscussionOutbox(channelId, topMsgId, readMaxId): + updatedState.readThread(threadMessageId: MessageId(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: channelId), namespace: Namespaces.Message.Cloud, id: topMsgId), readMaxId: readMaxId, isIncoming: false, mainChannelMessage: nil) case let .updateDialogUnreadMark(flags, peer): switch peer { case let .dialogPeer(peer): @@ -2535,7 +2543,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP case let .ReadGroupFeedInbox(groupId, index): break //transaction.applyGroupFeedReadMaxIndex(groupId: groupId, index: index) - case let .UpdateReadThread(threadMessageId, readMaxId, isIncoming): + case let .UpdateReadThread(threadMessageId, readMaxId, isIncoming, mainChannelMessage): if isIncoming { if let currentId = updatedIncomingThreadReadStates[threadMessageId] { if currentId < readMaxId { @@ -2544,6 +2552,22 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP } else { updatedIncomingThreadReadStates[threadMessageId] = readMaxId } + if let mainChannelMessage = mainChannelMessage { + transaction.updateMessage(mainChannelMessage, update: { currentMessage in + let storeForwardInfo = currentMessage.forwardInfo.flatMap(StoreMessageForwardInfo.init) + var attributes = currentMessage.attributes + loop: for j in 0 ..< attributes.count { + if let attribute = attributes[j] as? ReplyThreadMessageAttribute { + if let maxReadMessageId = attribute.maxReadMessageId, maxReadMessageId > readMaxId { + return .skip + } + attributes[j] = ReplyThreadMessageAttribute(count: attribute.count, latestUsers: attribute.latestUsers, commentsPeerId: attribute.commentsPeerId, maxMessageId: attribute.maxMessageId, maxReadMessageId: readMaxId) + return .update(StoreMessage(id: currentMessage.id, globallyUniqueId: currentMessage.globallyUniqueId, groupingKey: currentMessage.groupingKey, threadId: currentMessage.threadId, timestamp: currentMessage.timestamp, flags: StoreMessageFlags(currentMessage.flags), tags: currentMessage.tags, globalTags: currentMessage.globalTags, localTags: currentMessage.localTags, forwardInfo: storeForwardInfo, authorId: currentMessage.author?.id, text: currentMessage.text, attributes: attributes, media: currentMessage.media)) + } + } + return .skip + }) + } } else { if let currentId = updatedOutgoingThreadReadStates[threadMessageId] { if currentId < readMaxId { diff --git a/submodules/TelegramCore/Sources/ReplyThreadHistory.swift b/submodules/TelegramCore/Sources/ReplyThreadHistory.swift index 2af7b44ee5..615c87a202 100644 --- a/submodules/TelegramCore/Sources/ReplyThreadHistory.swift +++ b/submodules/TelegramCore/Sources/ReplyThreadHistory.swift @@ -33,7 +33,7 @@ private class ReplyThreadHistoryContextImpl { private var maxReadOutgoingMessageIdValue: MessageId? { didSet { if self.maxReadOutgoingMessageIdValue != oldValue { - self.maxReadOutgoingMessageId.set(.single(nil)) + self.maxReadOutgoingMessageId.set(.single(self.maxReadOutgoingMessageIdValue)) } } } diff --git a/submodules/TelegramUI/Resources/Animations/DiscussionGroupSetup.tgs b/submodules/TelegramUI/Resources/Animations/DiscussionGroupSetup.tgs new file mode 100644 index 0000000000..b513b9457a Binary files /dev/null and b/submodules/TelegramUI/Resources/Animations/DiscussionGroupSetup.tgs differ diff --git a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift index 685fd72db2..d016f05878 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryEntriesForView.swift @@ -95,7 +95,7 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, } else { selection = .none } - groupBucket.append((message, entry.isRead, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id]))) + groupBucket.append((message, isRead, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id]))) } else { let selection: ChatHistoryMessageSelection if let selectedMessages = selectedMessages { @@ -103,7 +103,7 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, } else { selection = .none } - entries.append(.MessageEntry(message, presentationData, entry.isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id]))) + entries.append(.MessageEntry(message, presentationData, isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id]))) } } else { let selection: ChatHistoryMessageSelection @@ -112,7 +112,7 @@ func chatHistoryEntriesForView(location: ChatLocation, view: MessageHistoryView, } else { selection = .none } - entries.append(.MessageEntry(message, presentationData, entry.isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id]))) + entries.append(.MessageEntry(message, presentationData, isRead, entry.monthLocation, selection, ChatMessageEntryAttributes(rank: adminRank, isContact: entry.attributes.authorIsContact, contentTypeHint: contentTypeHint, updatingMedia: updatingMedia[message.id]))) } } diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index 4ef9e6cb25..c53601ecd5 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -67,7 +67,7 @@ private func contentNodeMessagesAndClassesForItem(_ item: ChatMessageItem) -> [( result.append((message, ChatMessageActionBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .freeform))) } } else if let _ = media as? TelegramMediaMap { - result.append((message, ChatMessageMapBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .media))) + result.append((message, ChatMessageMapBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .freeform))) } else if let _ = media as? TelegramMediaGame { skipText = true result.append((message, ChatMessageGameBubbleContentNode.self, itemAttributes, BubbleItemAttributes(isAttachment: false, neighborType: .freeform))) diff --git a/submodules/TelegramUI/Sources/ChatSendMessageActionSheetControllerNode.swift b/submodules/TelegramUI/Sources/ChatSendMessageActionSheetControllerNode.swift index 29415a9bb9..4816c90d7b 100644 --- a/submodules/TelegramUI/Sources/ChatSendMessageActionSheetControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatSendMessageActionSheetControllerNode.swift @@ -395,7 +395,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, UIView.animate(withDuration: 0.2, animations: { if #available(iOS 9.0, *) { - self.effectView.effect = makeCustomZoomBlurEffect() + self.effectView.effect = makeCustomZoomBlurEffect(isLight: !self.presentationData.theme.overallDarkAppearance) } else { self.effectView.alpha = 1.0 } diff --git a/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.h b/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.h index 746f56d6c7..96e40fc67d 100644 --- a/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.h +++ b/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.h @@ -7,5 +7,5 @@ CABasicAnimation * _Nonnull makeSpringAnimationImpl(NSString * _Nonnull keyPath) CABasicAnimation * _Nonnull makeSpringBounceAnimationImpl(NSString * _Nonnull keyPath, CGFloat initialVelocity, CGFloat damping); CGFloat springAnimationValueAtImpl(CABasicAnimation * _Nonnull animation, CGFloat t); -UIBlurEffect *makeCustomZoomBlurEffectImpl(); +UIBlurEffect *makeCustomZoomBlurEffectImpl(bool isLight); void applySmoothRoundedCornersImpl(CALayer * _Nonnull layer); diff --git a/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.m b/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.m index c4a721b49a..76eac05f37 100644 --- a/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.m +++ b/submodules/UIKitRuntimeUtils/Source/UIKitRuntimeUtils/UIKitUtils.m @@ -159,9 +159,13 @@ static void setBoolField(CustomBlurEffect *object, NSString *name, BOOL value) { [inv invoke]; } -UIBlurEffect *makeCustomZoomBlurEffectImpl() { +UIBlurEffect *makeCustomZoomBlurEffectImpl(bool isLight) { if (@available(iOS 13.0, *)) { - return [UIBlurEffect effectWithStyle:UIBlurEffectStyleSystemUltraThinMaterialLight]; + if (isLight) { + return [UIBlurEffect effectWithStyle:UIBlurEffectStyleSystemUltraThinMaterialLight]; + } else { + return [UIBlurEffect effectWithStyle:UIBlurEffectStyleSystemUltraThinMaterialDark]; + } } else if (@available(iOS 11.0, *)) { NSString *string = [@[@"_", @"UI", @"Custom", @"BlurEffect"] componentsJoinedByString:@""]; CustomBlurEffect *result = (CustomBlurEffect *)[NSClassFromString(string) effectWithStyle:0];