diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 0ce626560f..cde68df6a7 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -8141,6 +8141,7 @@ Sorry for the inconvenience."; "ChatList.CloseAction" = "Close"; "Channel.EditAdmin.PermissionManageTopics" = "Manage Topics"; +"Channel.EditAdmin.PermissionCreateTopics" = "Create Topics"; "ChatList.Search.FilterTopics" = "Topics"; "DialogList.SearchSectionTopics" = "Topics"; @@ -8211,7 +8212,7 @@ Sorry for the inconvenience."; "PeerInfo.OptionTopicsText" = "The group chat will be divided into topics created by admins or users."; "PeerInfo.TopicsLimitedParticipantCountText_1" = "Only groups with more than **%d member** can have topics enabled."; "PeerInfo.TopicsLimitedParticipantCountText_any" = "Only groups with more than **%d members** can have topics enabled."; -"PeerInfo.TopicsLimitedDiscussionGroups" = "Topics are currently unavailable in groups connected to channels."; +"PeerInfo.TopicsLimitedDiscussionGroups" = "Topics can’t be enabled in discussion groups at the moment."; "PeerInfo.TopicNotificationExceptions_1" = "There is [1 topic]() that is listed as exception."; "PeerInfo.TopicNotificationExceptions_any" = "There are [%d topics]() that are listed as exceptions."; diff --git a/submodules/ChatListSearchRecentPeersNode/Sources/ChatListSearchRecentPeersNode.swift b/submodules/ChatListSearchRecentPeersNode/Sources/ChatListSearchRecentPeersNode.swift index 61c54f4826..bb86614f2e 100644 --- a/submodules/ChatListSearchRecentPeersNode/Sources/ChatListSearchRecentPeersNode.swift +++ b/submodules/ChatListSearchRecentPeersNode/Sources/ChatListSearchRecentPeersNode.swift @@ -10,6 +10,7 @@ import HorizontalPeerItem import ListSectionHeaderNode import ContextUI import AccountContext +import Postbox private func calculateItemCustomWidth(width: CGFloat) -> CGFloat { let itemInsets = UIEdgeInsets(top: 0.0, left: 6.0, bottom: 0.0, right: 6.0) @@ -155,51 +156,51 @@ public final class ChatListSearchRecentPeersNode: ASDisplayNode { } |> mapToSignal { recent in switch recent { - case .disabled: - return .single(([], [:], [:])) - case let .peers(peers): - return combineLatest(queue: .mainQueue(), - peers.filter { - !$0.isDeleted - }.map { - context.account.postbox.peerView(id: $0.id) - } - ) - |> mapToSignal { peerViews -> Signal<([EnginePeer], [EnginePeer.Id: (Int32, Bool)], [EnginePeer.Id: EnginePeer.Presence]), NoError> in - return context.account.postbox.unreadMessageCountsView(items: peerViews.map { - .peer($0.peerId) - }) - |> map { values in - var peers: [EnginePeer] = [] - var unread: [EnginePeer.Id: (Int32, Bool)] = [:] - var presences: [EnginePeer.Id: EnginePeer.Presence] = [:] - for peerView in peerViews { - if let peer = peerViewMainPeer(peerView) { - var isMuted: Bool = false - if let notificationSettings = peerView.notificationSettings as? TelegramPeerNotificationSettings { - switch notificationSettings.muteState { - case .muted: - isMuted = true - default: - break - } + case .disabled: + return .single(([], [:], [:])) + case let .peers(peers): + return combineLatest(queue: .mainQueue(), + peers.filter { + !$0.isDeleted + }.map { + context.account.postbox.peerView(id: $0.id) + } + ) + |> mapToSignal { peerViews -> Signal<([EnginePeer], [EnginePeer.Id: (Int32, Bool)], [EnginePeer.Id: EnginePeer.Presence]), NoError> in + return context.account.postbox.unreadMessageCountsView(items: peerViews.map { item -> UnreadMessageCountsItem in + return UnreadMessageCountsItem.peer(id: item.peerId, handleThreads: true) + }) + |> map { values in + var peers: [EnginePeer] = [] + var unread: [EnginePeer.Id: (Int32, Bool)] = [:] + var presences: [EnginePeer.Id: EnginePeer.Presence] = [:] + for peerView in peerViews { + if let peer = peerViewMainPeer(peerView) { + var isMuted: Bool = false + if let notificationSettings = peerView.notificationSettings as? TelegramPeerNotificationSettings { + switch notificationSettings.muteState { + case .muted: + isMuted = true + default: + break } - - let unreadCount = values.count(for: .peer(peerView.peerId)) - if let unreadCount = unreadCount, unreadCount > 0 { - unread[peerView.peerId] = (unreadCount, isMuted) - } - - if let presence = peerView.peerPresences[peer.id] { - presences[peer.id] = EnginePeer.Presence(presence) - } - - peers.append(EnginePeer(peer)) } + + let unreadCount = values.count(for: .peer(id: peerView.peerId, handleThreads: true)) + if let unreadCount = unreadCount, unreadCount > 0 { + unread[peerView.peerId] = (unreadCount, isMuted) + } + + if let presence = peerView.peerPresences[peer.id] { + presences[peer.id] = EnginePeer.Presence(presence) + } + + peers.append(EnginePeer(peer)) } - return (peers, unread, presences) } + return (peers, unread, presences) } + } } } diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 589910dec7..ff162d10df 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -1030,9 +1030,9 @@ public final class ChatListNode: ListView { } self?.setCurrentRemovingPeerId(nil) }) - }, setPeerThreadMuted: { [weak self] peerId, threadId, _ in + }, setPeerThreadMuted: { [weak self] peerId, threadId, value in //self?.setCurrentRemovingPeerId(peerId) - let _ = (context.engine.peers.togglePeerMuted(peerId: peerId, threadId: threadId) + let _ = (context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value ? Int32.max : 0) |> deliverOnMainQueue).start(completed: { self?.updateState { state in var state = state diff --git a/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift b/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift index e7a1b197cf..2f1421e815 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNodeLocation.swift @@ -203,11 +203,22 @@ func chatListViewForLocation(chatListLocation: ChatListControllerLocation, locat continue } + let defaultPeerNotificationSettings: TelegramPeerNotificationSettings = (view.peerNotificationSettings as? TelegramPeerNotificationSettings) ?? .defaultSettings + var hasUnseenMentions = false var isMuted = false - if case .muted = data.notificationSettings.muteState { + switch data.notificationSettings.muteState { + case .muted: isMuted = true + case .unmuted: + isMuted = false + case .default: + if case .default = data.notificationSettings.muteState { + if case .muted = defaultPeerNotificationSettings.muteState { + isMuted = true + } + } } if let info = item.tagSummaryInfo[ChatListEntryMessageTagSummaryKey( diff --git a/submodules/ChatListUI/Sources/TabBarChatListFilterController.swift b/submodules/ChatListUI/Sources/TabBarChatListFilterController.swift index f25162654c..a522e50c3d 100644 --- a/submodules/ChatListUI/Sources/TabBarChatListFilterController.swift +++ b/submodules/ChatListUI/Sources/TabBarChatListFilterController.swift @@ -26,7 +26,7 @@ func chatListFilterItems(context: AccountContext) -> Signal<(Int, [(ChatListFilt } if !additionalPeerIds.isEmpty { for peerId in additionalPeerIds { - unreadCountItems.append(.peer(peerId)) + unreadCountItems.append(.peer(id: peerId, handleThreads: true)) } } for groupId in additionalGroupIds { diff --git a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift index 5a6fa6749e..ac308efb11 100644 --- a/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift +++ b/submodules/MediaPickerUI/Sources/MediaPickerScreen.swift @@ -610,11 +610,16 @@ public final class MediaPickerScreen: ViewController, AttachmentContainable { hasTimer = true } + var hasSchedule = true + if controller.chatLocation?.threadId != nil { + hasSchedule = false + } + self.openingMedia = true let reversed = controller.collection == nil let index = reversed ? fetchResult.count - index - 1 : index - self.currentGalleryController = presentLegacyMediaPickerGallery(context: controller.context, peer: controller.peer, chatLocation: controller.chatLocation, presentationData: self.presentationData, source: .fetchResult(fetchResult: fetchResult, index: index, reversed: reversed), immediateThumbnail: immediateThumbnail, selectionContext: interaction.selectionState, editingContext: interaction.editingState, hasSilentPosting: true, hasSchedule: true, hasTimer: hasTimer, updateHiddenMedia: { [weak self] id in + self.currentGalleryController = presentLegacyMediaPickerGallery(context: controller.context, peer: controller.peer, chatLocation: controller.chatLocation, presentationData: self.presentationData, source: .fetchResult(fetchResult: fetchResult, index: index, reversed: reversed), immediateThumbnail: immediateThumbnail, selectionContext: interaction.selectionState, editingContext: interaction.editingState, hasSilentPosting: true, hasSchedule: hasSchedule, hasTimer: hasTimer, updateHiddenMedia: { [weak self] id in self?.hiddenMediaId.set(.single(id)) }, initialLayout: layout, transitionHostView: { [weak self] in return self?.gridNode.view diff --git a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift index d86049d007..d3c7e2dc42 100644 --- a/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelDiscussionGroupSetupController.swift @@ -15,6 +15,7 @@ import PresentationDataUtils import ItemListPeerItem import ItemListPeerActionItem import ChatListFilterSettingsHeaderItem +import UndoUI private final class ChannelDiscussionGroupSetupControllerArguments { let context: AccountContext @@ -314,6 +315,13 @@ public func channelDiscussionGroupSetupController(context: AccountContext, updat } let presentationData = context.sharedContext.currentPresentationData.with { $0 } + + if case let .channel(channel) = groupPeer, channel.flags.contains(.isForum) { + let text = presentationData.strings.PeerInfo_TopicsLimitedDiscussionGroups + presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_topics", scale: 0.066, colors: [:], title: nil, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), nil) + return + } + let actionSheet = ActionSheetController(presentationData: presentationData) actionSheet.setItemGroups([ActionSheetItemGroup(items: [ ChannelDiscussionGroupActionSheetItem(context: context, channelPeer: channelPeer._asPeer(), groupPeer: groupPeer._asPeer(), strings: presentationData.strings, nameDisplayOrder: presentationData.nameDisplayOrder), diff --git a/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift b/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift index cd06ea1325..1010b50907 100644 --- a/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelPermissionsController.swift @@ -354,7 +354,7 @@ func stringForGroupPermission(strings: PresentationStrings, right: TelegramChatB } else if right.contains(.banPinMessages) { return strings.Channel_EditAdmin_PermissionPinMessages } else if right.contains(.banManageTopics) { - return strings.Channel_EditAdmin_PermissionManageTopics + return strings.Channel_EditAdmin_PermissionCreateTopics } else { return "" } diff --git a/submodules/Postbox/Sources/MessageHistoryThreadIndexView.swift b/submodules/Postbox/Sources/MessageHistoryThreadIndexView.swift index 8d7f30da7a..8c1a57f695 100644 --- a/submodules/Postbox/Sources/MessageHistoryThreadIndexView.swift +++ b/submodules/Postbox/Sources/MessageHistoryThreadIndexView.swift @@ -32,6 +32,7 @@ final class MutableMessageHistoryThreadIndexView: MutablePostboxView { fileprivate let peerId: PeerId fileprivate let summaryComponents: ChatListEntrySummaryComponents fileprivate var peer: Peer? + fileprivate var peerNotificationSettings: PeerNotificationSettings? fileprivate var items: [Item] = [] private var hole: ForumTopicListHolesEntry? fileprivate var isLoading: Bool = false @@ -48,6 +49,8 @@ final class MutableMessageHistoryThreadIndexView: MutablePostboxView { self.peer = postbox.peerTable.get(self.peerId) + self.peerNotificationSettings = postbox.peerNotificationSettingsTable.getEffective(self.peerId) + let validIndexBoundary = postbox.peerThreadCombinedStateTable.get(peerId: peerId)?.validIndexBoundary self.isLoading = validIndexBoundary == nil @@ -128,7 +131,7 @@ final class MutableMessageHistoryThreadIndexView: MutablePostboxView { func replay(postbox: PostboxImpl, transaction: PostboxTransaction) -> Bool { var updated = false - if transaction.updatedMessageThreadPeerIds.contains(self.peerId) || transaction.updatedPinnedThreads.contains(self.peerId) || transaction.updatedPeerThreadCombinedStates.contains(self.peerId) || transaction.currentUpdatedMessageTagSummaries.contains(where: { $0.key.peerId == self.peerId }) || transaction.currentUpdatedMessageActionsSummaries.contains(where: { $0.key.peerId == self.peerId }) || transaction.currentUpdatedPeerChatListEmbeddedStates.contains(self.peerId) { + if transaction.updatedMessageThreadPeerIds.contains(self.peerId) || transaction.updatedPinnedThreads.contains(self.peerId) || transaction.updatedPeerThreadCombinedStates.contains(self.peerId) || transaction.currentUpdatedMessageTagSummaries.contains(where: { $0.key.peerId == self.peerId }) || transaction.currentUpdatedMessageActionsSummaries.contains(where: { $0.key.peerId == self.peerId }) || transaction.currentUpdatedPeerChatListEmbeddedStates.contains(self.peerId) || transaction.currentUpdatedPeerNotificationSettings[self.peerId] != nil { self.reload(postbox: postbox) updated = true } @@ -216,11 +219,13 @@ public final class EngineMessageHistoryThread { public final class MessageHistoryThreadIndexView: PostboxView { public let peer: Peer? + public let peerNotificationSettings: PeerNotificationSettings? public let items: [EngineMessageHistoryThread.Item] public let isLoading: Bool init(_ view: MutableMessageHistoryThreadIndexView) { self.peer = view.peer + self.peerNotificationSettings = view.peerNotificationSettings var items: [EngineMessageHistoryThread.Item] = [] for item in view.items { diff --git a/submodules/Postbox/Sources/UnreadMessageCountsView.swift b/submodules/Postbox/Sources/UnreadMessageCountsView.swift index 72d37aeb03..aabb2070dd 100644 --- a/submodules/Postbox/Sources/UnreadMessageCountsView.swift +++ b/submodules/Postbox/Sources/UnreadMessageCountsView.swift @@ -3,13 +3,13 @@ import Foundation public enum UnreadMessageCountsItem: Equatable { case total(ValueBoxKey?) case totalInGroup(PeerGroupId) - case peer(PeerId) + case peer(id: PeerId, handleThreads: Bool) } private enum MutableUnreadMessageCountsItemEntry: Equatable { case total((ValueBoxKey, PreferencesEntry?)?, ChatListTotalUnreadState) case totalInGroup(PeerGroupId, ChatListTotalUnreadState) - case peer(PeerId, CombinedPeerReadState?) + case peer(PeerId, Bool, CombinedPeerReadState?) static func ==(lhs: MutableUnreadMessageCountsItemEntry, rhs: MutableUnreadMessageCountsItemEntry) -> Bool { switch lhs { @@ -34,8 +34,8 @@ private enum MutableUnreadMessageCountsItemEntry: Equatable { } else { return false } - case let .peer(peerId, readState): - if case .peer(peerId, readState) = rhs { + case let .peer(peerId, handleThreads, readState): + if case .peer(peerId, handleThreads, readState) = rhs { return true } else { return false @@ -63,15 +63,15 @@ final class MutableUnreadMessageCountsView: MutablePostboxView { return .total(preferencesKey.flatMap({ ($0, postbox.preferencesTable.get(key: $0)) }), postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: .root)) case let .totalInGroup(groupId): return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId)) - case let .peer(peerId): - if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) { + case let .peer(peerId, handleThreads): + if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) { var count: Int32 = 0 if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) { count = summary.effectiveUnreadCount } - return .peer(peerId, CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 1, maxOutgoingReadId: 1, maxKnownId: 1, count: count, markedUnread: false))])) + return .peer(peerId, handleThreads, CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 1, maxOutgoingReadId: 1, maxKnownId: 1, count: count, markedUnread: false))])) } else { - return .peer(peerId, postbox.readStateTable.getCombinedState(peerId)) + return .peer(peerId, handleThreads, postbox.readStateTable.getCombinedState(peerId)) } } } @@ -112,19 +112,19 @@ final class MutableUnreadMessageCountsView: MutablePostboxView { updated = true } } - case let .peer(peerId, _): - if let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) { + case let .peer(peerId, handleThreads, _): + if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) { if transaction.updatedPeerThreadsSummaries.contains(peerId) { var count: Int32 = 0 if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) { count = summary.effectiveUnreadCount } - self.entries[i] = .peer(peerId, CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 1, maxOutgoingReadId: 1, maxKnownId: 1, count: count, markedUnread: false))])) + self.entries[i] = .peer(peerId, handleThreads, CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 1, maxOutgoingReadId: 1, maxKnownId: 1, count: count, markedUnread: false))])) updated = true } } else { if transaction.alteredInitialPeerCombinedReadStates[peerId] != nil { - self.entries[i] = .peer(peerId, postbox.readStateTable.getCombinedState(peerId)) + self.entries[i] = .peer(peerId, handleThreads, postbox.readStateTable.getCombinedState(peerId)) updated = true } } @@ -142,8 +142,16 @@ final class MutableUnreadMessageCountsView: MutablePostboxView { return .total(preferencesKey.flatMap({ ($0, postbox.preferencesTable.get(key: $0)) }), postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: .root)) case let .totalInGroup(groupId): return .totalInGroup(groupId, postbox.messageHistoryMetadataTable.getTotalUnreadState(groupId: groupId)) - case let .peer(peerId): - return .peer(peerId, postbox.readStateTable.getCombinedState(peerId)) + case let .peer(peerId, handleThreads): + if handleThreads, let peer = postbox.peerTable.get(peerId), postbox.seedConfiguration.peerSummaryIsThreadBased(peer) { + var count: Int32 = 0 + if let summary = postbox.peerThreadsSummaryTable.get(peerId: peerId) { + count = summary.effectiveUnreadCount + } + return .peer(peerId, handleThreads, CombinedPeerReadState(states: [(0, .idBased(maxIncomingReadId: 1, maxOutgoingReadId: 1, maxKnownId: 1, count: count, markedUnread: false))])) + } else { + return .peer(peerId, handleThreads, postbox.readStateTable.getCombinedState(peerId)) + } } } if self.entries != entries { @@ -169,7 +177,7 @@ public final class UnreadMessageCountsView: PostboxView { return .total(keyAndValue?.1, state) case let .totalInGroup(groupId, state): return .totalInGroup(groupId, state) - case let .peer(peerId, count): + case let .peer(peerId, _, count): return .peer(peerId, count) } } @@ -193,7 +201,7 @@ public final class UnreadMessageCountsView: PostboxView { case .total, .totalInGroup: break case let .peer(peerId, state): - if case .peer(peerId) = item { + if case .peer(peerId, _) = item { return state?.count ?? 0 } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift b/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift index 44face9eb7..a8efaaf490 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Data/MessagesData.swift @@ -194,7 +194,7 @@ public extension TelegramEngine.EngineData.Item { } var key: PostboxViewKey { - return .unreadCounts(items: [.peer(self.id)]) + return .unreadCounts(items: [.peer(id: self.id, handleThreads: true)]) } public init(id: EnginePeer.Id) { @@ -206,7 +206,7 @@ public extension TelegramEngine.EngineData.Item { preconditionFailure() } - return Int(view.count(for: .peer(self.id)) ?? 0) + return Int(view.count(for: .peer(id: self.id, handleThreads: true)) ?? 0) } } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChangePeerNotificationSettings.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChangePeerNotificationSettings.swift index 69fb6cfd56..c170533080 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChangePeerNotificationSettings.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/ChangePeerNotificationSettings.swift @@ -71,10 +71,12 @@ func _internal_updatePeerMuteSetting(account: Account, peerId: PeerId, threadId: func _internal_updatePeerMuteSetting(account: Account, transaction: Transaction, peerId: PeerId, threadId: Int64?, muteInterval: Int32?) { if let peer = transaction.getPeer(peerId) { if let threadId = threadId { + let peerSettings: TelegramPeerNotificationSettings = (transaction.getPeerNotificationSettings(id: peerId) as? TelegramPeerNotificationSettings) ?? .defaultSettings + if var data = transaction.getMessageHistoryThreadInfo(peerId: peerId, threadId: threadId)?.data.get(MessageHistoryThreadData.self) { let previousSettings: TelegramPeerNotificationSettings = data.notificationSettings - let muteState: PeerMuteState + var muteState: PeerMuteState if let muteInterval = muteInterval { if muteInterval == 0 { muteState = .unmuted @@ -88,6 +90,9 @@ func _internal_updatePeerMuteSetting(account: Account, transaction: Transaction, muteState = .muted(until: absoluteUntil) } } else { + muteState = .unmuted + } + if peerSettings.muteState == muteState { muteState = .default } diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/RecentlySearchedPeerIds.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/RecentlySearchedPeerIds.swift index f611f03399..56cf52a787 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/RecentlySearchedPeerIds.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/RecentlySearchedPeerIds.swift @@ -46,7 +46,7 @@ func _internal_recentlySearchedPeers(postbox: Postbox) -> Signal<[RecentlySearch } } var keys: [PostboxViewKey] = [] - let unreadCountsKey: PostboxViewKey = .unreadCounts(items: peerIds.map(UnreadMessageCountsItem.peer)) + let unreadCountsKey: PostboxViewKey = .unreadCounts(items: peerIds.map { UnreadMessageCountsItem.peer(id: $0, handleThreads: true) }) keys.append(unreadCountsKey) keys.append(contentsOf: peerIds.map({ .peer(peerId: $0, components: .all) })) diff --git a/submodules/TelegramUI/Sources/AccountContext.swift b/submodules/TelegramUI/Sources/AccountContext.swift index 76eed4af3d..9be65ceaff 100644 --- a/submodules/TelegramUI/Sources/AccountContext.swift +++ b/submodules/TelegramUI/Sources/AccountContext.swift @@ -384,13 +384,13 @@ public final class AccountContextImpl: AccountContext { public func chatLocationUnreadCount(for location: ChatLocation, contextHolder: Atomic) -> Signal { switch location { case let .peer(peerId): - let unreadCountsKey: PostboxViewKey = .unreadCounts(items: [.peer(peerId), .total(nil)]) + let unreadCountsKey: PostboxViewKey = .unreadCounts(items: [.peer(id: peerId, handleThreads: false), .total(nil)]) return self.account.postbox.combinedView(keys: [unreadCountsKey]) |> map { views in var unreadCount: Int32 = 0 if let view = views.views[unreadCountsKey] as? UnreadMessageCountsView { - if let count = view.count(for: .peer(peerId)) { + if let count = view.count(for: .peer(id: peerId, handleThreads: false)) { unreadCount = count } } diff --git a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift index 9761bfd768..cca0a9497a 100644 --- a/submodules/TelegramUI/Sources/ChatMediaInputNode.swift +++ b/submodules/TelegramUI/Sources/ChatMediaInputNode.swift @@ -1618,18 +1618,20 @@ final class ChatMediaInputNode: ChatInputNode { }))) } - menuItems.append(.action(ContextMenuActionItem(text: strongSelf.strings.Conversation_SendMessage_ScheduleMessage, icon: { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/ScheduleIcon"), color: theme.actionSheet.primaryTextColor) - }, action: { _, f in - if let strongSelf = self, let peekController = strongSelf.peekController { - if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode { - let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, animationNode.view, animationNode.bounds, nil, []) - } else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode { - let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, imageNode.view, imageNode.bounds, nil, []) + if interfaceState.chatLocation.threadId == nil { + menuItems.append(.action(ContextMenuActionItem(text: strongSelf.strings.Conversation_SendMessage_ScheduleMessage, icon: { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/ScheduleIcon"), color: theme.actionSheet.primaryTextColor) + }, action: { _, f in + if let strongSelf = self, let peekController = strongSelf.peekController { + if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode { + let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, animationNode.view, animationNode.bounds, nil, []) + } else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode { + let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, imageNode.view, imageNode.bounds, nil, []) + } } - } - f(.default) - }))) + f(.default) + }))) + } } } } @@ -1770,18 +1772,20 @@ final class ChatMediaInputNode: ChatInputNode { }))) } - menuItems.append(.action(ContextMenuActionItem(text: strongSelf.strings.Conversation_SendMessage_ScheduleMessage, icon: { theme in - return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/ScheduleIcon"), color: theme.actionSheet.primaryTextColor) - }, action: { _, f in - if let strongSelf = self, let peekController = strongSelf.peekController { - if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode { - let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, animationNode.view, animationNode.bounds, nil, []) - } else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode { - let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, imageNode.view, imageNode.bounds, nil, []) + if interfaceState.chatLocation.threadId == nil { + menuItems.append(.action(ContextMenuActionItem(text: strongSelf.strings.Conversation_SendMessage_ScheduleMessage, icon: { theme in + return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Menu/ScheduleIcon"), color: theme.actionSheet.primaryTextColor) + }, action: { _, f in + if let strongSelf = self, let peekController = strongSelf.peekController { + if let animationNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.animationNode { + let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, animationNode.view, animationNode.bounds, nil, []) + } else if let imageNode = (peekController.contentNode as? StickerPreviewPeekContentNode)?.imageNode { + let _ = strongSelf.controllerInteraction.sendSticker(.standalone(media: item.file), false, true, nil, false, imageNode.view, imageNode.bounds, nil, []) + } } - } - f(.default) - }))) + f(.default) + }))) + } } } } diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index dbbbca6ba8..5171642c47 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -1397,7 +1397,13 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode authorRank = attributes.rank } - if authorRank == nil { + var enableAutoRank = false + if let authorRank = authorRank, case .admin = authorRank { + enableAutoRank = true + } else if authorRank == nil { + enableAutoRank = true + } + if enableAutoRank { if let topicAuthorId = item.associatedData.topicAuthorId, topicAuthorId == message.author?.id { authorRank = .custom(item.presentationData.strings.Chat_Message_TopicAuthorBadge) } diff --git a/submodules/UrlWhitelist/Sources/UrlWhitelist.swift b/submodules/UrlWhitelist/Sources/UrlWhitelist.swift index 4321d495b8..2b76a6938d 100644 --- a/submodules/UrlWhitelist/Sources/UrlWhitelist.swift +++ b/submodules/UrlWhitelist/Sources/UrlWhitelist.swift @@ -4,7 +4,8 @@ private let whitelistedHosts: Set = Set([ "t.me", "telegram.me", "telegra.ph", - "telesco.pe" + "telesco.pe", + "fragment.com" ]) public func isConcealedUrlWhitelisted(_ url: URL) -> Bool {