diff --git a/submodules/ChatListUI/Sources/ChatContextMenus.swift b/submodules/ChatListUI/Sources/ChatContextMenus.swift index f4644d9a8c..b27d1b291b 100644 --- a/submodules/ChatListUI/Sources/ChatContextMenus.swift +++ b/submodules/ChatListUI/Sources/ChatContextMenus.swift @@ -747,7 +747,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId: let canRemove = false - let exceptionController = notificationPeerExceptionController(context: context, updatedPresentationData: nil, peer: .channel(channel), threadId: threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, edit: true, updatePeerSound: { peerId, sound in + let exceptionController = notificationPeerExceptionController(context: context, updatedPresentationData: nil, peer: .channel(channel), threadId: threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, defaultStoriesSound: defaultSound, edit: true, updatePeerSound: { peerId, sound in let _ = (updatePeerSound(peerId, sound) |> deliverOnMainQueue).start(next: { _ in }) diff --git a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift index 12126be1ea..336ce4ce85 100644 --- a/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift +++ b/submodules/SettingsUI/Sources/Notifications/Exceptions/NotificationExceptionControllerNode.swift @@ -643,11 +643,11 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode { case .users: defaultSound = globalSettings.privateChats.sound._asMessageSound() case .stories: - defaultSound = globalSettings.privateChats.sound._asMessageSound() + defaultSound = globalSettings.privateChats.storySettings.sound isStories = true } - presentControllerImpl?(notificationPeerExceptionController(context: context, peer: peer, threadId: nil, isStories: isStories, canRemove: canRemove, defaultSound: defaultSound, updatePeerSound: { peerId, sound in + presentControllerImpl?(notificationPeerExceptionController(context: context, peer: peer, threadId: nil, isStories: isStories, canRemove: canRemove, defaultSound: defaultSound, defaultStoriesSound: defaultSound, updatePeerSound: { peerId, sound in _ = updatePeerSound(peer.id, sound).start(next: { _ in updateNotificationsDisposable.set(nil) _ = combineLatest(updatePeerSound(peer.id, sound), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in diff --git a/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift b/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift index 4823ec1f34..4c44a9cbae 100644 --- a/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift +++ b/submodules/SettingsUI/Sources/NotificationsPeerCategoryController.swift @@ -91,6 +91,19 @@ public enum NotificationsPeerCategoryEntryTag: ItemListItemTag { } private enum NotificationsPeerCategoryEntry: ItemListNodeEntry { + enum StableId: Hashable { + case enable + case enableImportant + case importantInfo + case optionsHeader + case previews + case sound + case exceptionsHeader + case addException + case peer(EnginePeer.Id) + case removeAllExceptions + } + case enable(PresentationTheme, String, Bool) case enableImportant(PresentationTheme, String, Bool) case importantInfo(PresentationTheme, String) @@ -100,7 +113,7 @@ private enum NotificationsPeerCategoryEntry: ItemListNodeEntry { case exceptionsHeader(PresentationTheme, String) case addException(PresentationTheme, String) - case exception(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, EnginePeer, String, TelegramPeerNotificationSettings, Bool, Bool) + case exception(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, EnginePeer, String, TelegramPeerNotificationSettings, Bool, Bool, Bool) case removeAllExceptions(PresentationTheme, String) var section: ItemListSectionId { @@ -114,28 +127,53 @@ private enum NotificationsPeerCategoryEntry: ItemListNodeEntry { } } - var stableId: Int32 { + var stableId: StableId { switch self { - case .enable: - return 0 - case .enableImportant: - return 1 - case .importantInfo: - return 2 - case .optionsHeader: - return 3 - case .previews: - return 4 - case .sound: - return 5 - case .exceptionsHeader: - return 6 - case .addException: - return 7 - case let .exception(index, _, _, _, _, _, _, _, _, _): - return 8 + index - case .removeAllExceptions: - return 100000 + case .enable: + return .enable + case .enableImportant: + return .enableImportant + case .importantInfo: + return .importantInfo + case .optionsHeader: + return .optionsHeader + case .previews: + return .previews + case .sound: + return .sound + case .exceptionsHeader: + return .exceptionsHeader + case .addException: + return .addException + case let .exception(_, _, _, _, _, peer, _, _, _, _, _): + return .peer(peer.id) + case .removeAllExceptions: + return .removeAllExceptions + } + } + + var sortIndex: Int32 { + switch self { + case .enable: + return 0 + case .enableImportant: + return 1 + case .importantInfo: + return 2 + case .optionsHeader: + return 3 + case .previews: + return 4 + case .sound: + return 5 + case .exceptionsHeader: + return 6 + case .addException: + return 7 + case let .exception(index, _, _, _, _, _, _, _, _, _, _): + return 100 + index + case .removeAllExceptions: + return 10000 } } @@ -202,8 +240,8 @@ private enum NotificationsPeerCategoryEntry: ItemListNodeEntry { } else { return false } - case let .exception(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsDisplayNameOrder, lhsPeer, lhsDescription, lhsSettings, lhsEditing, lhsRevealed): - if case let .exception(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsDisplayNameOrder, rhsPeer, rhsDescription, rhsSettings, rhsEditing, rhsRevealed) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsDisplayNameOrder == rhsDisplayNameOrder, lhsPeer == rhsPeer, lhsDescription == rhsDescription, lhsSettings == rhsSettings, lhsEditing == rhsEditing, lhsRevealed == rhsRevealed { + case let .exception(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsDisplayNameOrder, lhsPeer, lhsDescription, lhsSettings, lhsEditing, lhsRevealed, lhsCanRemove): + if case let .exception(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsDisplayNameOrder, rhsPeer, rhsDescription, rhsSettings, rhsEditing, rhsRevealed, rhsCanRemove) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsDisplayNameOrder == rhsDisplayNameOrder, lhsPeer == rhsPeer, lhsDescription == rhsDescription, lhsSettings == rhsSettings, lhsEditing == rhsEditing, lhsRevealed == rhsRevealed, lhsCanRemove == rhsCanRemove { return true } else { return false @@ -219,7 +257,7 @@ private enum NotificationsPeerCategoryEntry: ItemListNodeEntry { } static func <(lhs: NotificationsPeerCategoryEntry, rhs: NotificationsPeerCategoryEntry) -> Bool { - return lhs.stableId < rhs.stableId + return lhs.sortIndex < rhs.sortIndex } func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem { @@ -251,8 +289,8 @@ private enum NotificationsPeerCategoryEntry: ItemListNodeEntry { return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.plusIconImage(theme), title: text, sectionId: self.section, height: .peerList, color: .accent, editing: false, action: { arguments.addException() }) - case let .exception(_, _, _, dateTimeFormat, nameDisplayOrder, peer, description, _, editing, revealed): - return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer, presence: nil, text: .text(description, .secondary), label: .none, editing: ItemListPeerItemEditing(editable: true, editing: editing, revealed: revealed), switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: { + case let .exception(_, _, _, dateTimeFormat, nameDisplayOrder, peer, description, _, editing, revealed, canRemove): + return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer, presence: nil, text: .text(description, .secondary), label: .none, editing: ItemListPeerItemEditing(editable: canRemove, editing: canRemove && editing, revealed: canRemove && revealed), switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: { arguments.openException(peer) }, setPeerIdWithRevealedOptions: { peerId, fromPeerId in arguments.updateRevealedPeerId(peerId) @@ -371,11 +409,13 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor for (_, value) in sortedExceptions { if !value.peer.isDeleted { + var canRemove = true var title: String = "" if automaticSet.contains(value.peer.id) { //TODO:localize title = "\(presentationData.strings.Notification_Exceptions_AlwaysOn) (automatic)" + canRemove = false } else { if case .stories = category { var muted = false @@ -468,7 +508,7 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor } } existingPeerIds.insert(value.peer.id) - entries.append(.exception(Int32(index), presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, value.peer, title, value.settings, state.editing, state.revealedPeerId == value.peer.id)) + entries.append(.exception(Int32(index), presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, value.peer, title, value.settings, state.editing, state.revealedPeerId == value.peer.id, canRemove)) index += 1 } } @@ -534,6 +574,10 @@ private final class NotificationExceptionState : Equatable { return NotificationExceptionState(mode: mode.withUpdatedPeerStorySound(peer, sound), revealedPeerId: self.revealedPeerId, editing: self.editing) } + func removeStoryPeerIfDefault(id: EnginePeer.Id) -> NotificationExceptionState { + return NotificationExceptionState(mode: mode.removeStoryPeerIfDefault(id: id), revealedPeerId: self.revealedPeerId, editing: self.editing) + } + static func == (lhs: NotificationExceptionState, rhs: NotificationExceptionState) -> Bool { return lhs.mode == rhs.mode && lhs.revealedPeerId == rhs.revealedPeerId && lhs.editing == rhs.editing } @@ -655,11 +699,11 @@ public func notificationsPeerCategoryController(context: AccountContext, categor case .users: defaultSound = globalSettings.privateChats.sound._asMessageSound() case .stories: - defaultSound = globalSettings.privateChats.sound._asMessageSound() + defaultSound = globalSettings.privateChats.storySettings.sound isStories = true } - pushControllerImpl?(notificationPeerExceptionController(context: context, peer: peer, threadId: nil, isStories: isStories, canRemove: canRemove, defaultSound: defaultSound, updatePeerSound: { peerId, sound in + pushControllerImpl?(notificationPeerExceptionController(context: context, peer: peer, threadId: nil, isStories: isStories, canRemove: canRemove, defaultSound: defaultSound, defaultStoriesSound: defaultSound, updatePeerSound: { peerId, sound in _ = updatePeerSound(peer.id, sound).start(next: { _ in updateNotificationsDisposable.set(nil) _ = combineLatest(updatePeerSound(peer.id, sound), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in @@ -732,7 +776,9 @@ public func notificationsPeerCategoryController(context: AccountContext, categor return } updateState { value in - return value.withUpdatedPeerStorySound(peer, .default).withUpdatedPeerStoriesMuted(peer, .default).withUpdatedPeerStoriesHideSender(peer, .default) + var value = value.withUpdatedPeerStorySound(peer, .default).withUpdatedPeerStoriesMuted(peer, .default).withUpdatedPeerStoriesHideSender(peer, .default) + value = value.removeStoryPeerIfDefault(id: peer.id) + return value } updateNotificationsView({}) }) @@ -858,6 +904,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor var state = state for value in values { state = state.withUpdatedPeerStorySound(value.peer, .default).withUpdatedPeerStoriesMuted(value.peer, .default).withUpdatedPeerStoriesHideSender(value.peer, .default) + state = state.removeStoryPeerIfDefault(id: value.peer.id) } return state } @@ -900,7 +947,9 @@ public func notificationsPeerCategoryController(context: AccountContext, categor |> deliverOnMainQueue).start(completed: { updateNotificationsDisposable.set(nil) updateState { value in - return value.withUpdatedPeerStorySound(peer, .default).withUpdatedPeerStoriesMuted(peer, .default).withUpdatedPeerStoriesHideSender(peer, .default) + var value = value.withUpdatedPeerStorySound(peer, .default).withUpdatedPeerStoriesMuted(peer, .default).withUpdatedPeerStoriesHideSender(peer, .default) + value = value.removeStoryPeerIfDefault(id: peer.id) + return value } let _ = (context.engine.peers.removeCustomStoryNotificationSettings(peerIds: [peer.id]) |> deliverOnMainQueue).start(completed: { diff --git a/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift b/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift index 68fb59d54b..615cc5965e 100644 --- a/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift +++ b/submodules/TelegramUI/Components/NotificationExceptionsScreen/Sources/NotificationExceptionsScreen.swift @@ -466,7 +466,7 @@ public func threadNotificationExceptionsScreen(context: AccountContext, peerId: let canRemove = true let defaultSound: PeerMessageSound = globalSettings.groupChats.sound._asMessageSound() - pushControllerImpl?(notificationPeerExceptionController(context: context, peer: peer, customTitle: item.info.title, threadId: item.threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, updatePeerSound: { _, sound in + pushControllerImpl?(notificationPeerExceptionController(context: context, peer: peer, customTitle: item.info.title, threadId: item.threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, defaultStoriesSound: defaultSound, updatePeerSound: { _, sound in let _ = (updateThreadSound(item.threadId, sound) |> deliverOnMainQueue).start(next: { _ in updateState { value in diff --git a/submodules/TelegramUI/Components/NotificationPeerExceptionController/Sources/NotificationPeerExceptionController.swift b/submodules/TelegramUI/Components/NotificationPeerExceptionController/Sources/NotificationPeerExceptionController.swift index 4c7298fb38..13250d0502 100644 --- a/submodules/TelegramUI/Components/NotificationPeerExceptionController/Sources/NotificationPeerExceptionController.swift +++ b/submodules/TelegramUI/Components/NotificationPeerExceptionController/Sources/NotificationPeerExceptionController.swift @@ -368,6 +368,25 @@ public enum NotificationExceptionMode : Equatable { } } + public func removeStoryPeerIfDefault(id: EnginePeer.Id) -> NotificationExceptionMode { + switch self { + case let .stories(values): + if let settings = values[id]?.settings { + if settings.storySettings == .default { + var values = values + values.removeValue(forKey: id) + return .stories(values) + } else { + return .stories(values) + } + } else { + return .stories(values) + } + default: + return self + } + } + public var peerIds: [EnginePeer.Id] { switch self { case let .users(settings), let .groups(settings), let .channels(settings), let .stories(settings): @@ -735,6 +754,8 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData } if displaySounds { + let defaultSound = isStories == true ? state.defaultStoriesSound : state.defaultSound + entries.append(.cloudHeader(index: index, text: presentationData.strings.Notifications_TelegramTones)) index += 1 @@ -765,7 +786,7 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData index = 3000 - entries.append(.default(index: index, section: .soundModern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: .default, default: state.defaultSound), selected: selectedSound == .default)) + entries.append(.default(index: index, section: .soundModern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: .default, default: defaultSound), selected: selectedSound == .default)) index += 1 entries.append(.none(index: index, section: .soundModern, theme: presentationData.theme, text: localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: .none), selected: selectedSound == .none)) @@ -797,6 +818,7 @@ private struct NotificationExceptionPeerState : Equatable { var mode: NotificationPeerExceptionSwitcher var defaultSound: PeerMessageSound var displayPreviews: NotificationPeerExceptionSwitcher + var defaultStoriesSound: PeerMessageSound var storiesMuted: NotificationPeerExceptionSwitcher var selectedStoriesSound: PeerMessageSound var storiesHideSender: NotificationPeerExceptionSwitcher @@ -827,6 +849,7 @@ private struct NotificationExceptionPeerState : Equatable { } self.defaultSound = .default + self.defaultStoriesSound = .default self.removedSounds = [] } @@ -836,6 +859,7 @@ private struct NotificationExceptionPeerState : Equatable { mode: NotificationPeerExceptionSwitcher, defaultSound: PeerMessageSound, displayPreviews: NotificationPeerExceptionSwitcher, + defaultStoriesSound: PeerMessageSound, storiesMuted: NotificationPeerExceptionSwitcher, selectedStoriesSound: PeerMessageSound, storiesHideSender: NotificationPeerExceptionSwitcher, @@ -846,6 +870,7 @@ private struct NotificationExceptionPeerState : Equatable { self.mode = mode self.defaultSound = defaultSound self.displayPreviews = displayPreviews + self.defaultStoriesSound = defaultStoriesSound self.storiesMuted = storiesMuted self.selectedStoriesSound = selectedStoriesSound self.storiesHideSender = storiesHideSender @@ -862,6 +887,7 @@ public func notificationPeerExceptionController( isStories: Bool?, canRemove: Bool, defaultSound: PeerMessageSound, + defaultStoriesSound: PeerMessageSound, edit: Bool = false, updatePeerSound: @escaping(EnginePeer.Id, PeerMessageSound) -> Void, updatePeerNotificationInterval: @escaping(EnginePeer.Id, Int32?) -> Void, @@ -894,7 +920,7 @@ public func notificationPeerExceptionController( let _ = (context.engine.peers.notificationSoundList() |> take(1) |> deliverOnMainQueue).start(next: { notificationSoundList in - playSoundDisposable.set(playSound(context: context, notificationSoundList: notificationSoundList, sound: sound, defaultSound: state.defaultSound).start()) + playSoundDisposable.set(playSound(context: context, notificationSoundList: notificationSoundList, sound: sound, defaultSound: state.defaultStoriesSound).start()) }) var state = state @@ -943,7 +969,7 @@ public func notificationPeerExceptionController( let _ = (context.engine.peers.notificationSoundList() |> take(1) |> deliverOnMainQueue).start(next: { notificationSoundList in - playSoundDisposable.set(playSound(context: context, notificationSoundList: notificationSoundList, sound: sound, defaultSound: state.defaultSound).start()) + playSoundDisposable.set(playSound(context: context, notificationSoundList: notificationSoundList, sound: sound, defaultSound: state.defaultStoriesSound).start()) }) var state = state @@ -972,6 +998,7 @@ public func notificationPeerExceptionController( var state = NotificationExceptionPeerState(canRemove: canRemove, notifications: effectiveSettings._asNotificationSettings()) state.defaultSound = defaultSound + state.defaultStoriesSound = defaultStoriesSound let _ = stateValue.swap(state) return state }) diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 5100cfdf90..c4c716b161 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -1003,8 +1003,15 @@ public final class StoryItemSetContainerComponent: Component { guard let component = self.component else { return nil } - if component.slice.peer.id == component.context.account.peerId { - } else { + + var canReply = true + if component.slice.peer.isService { + canReply = false + } else if case .unsupported = component.slice.item.storyItem.media { + canReply = false + } + + if canReply { if let inputPanelView = self.inputPanel.view as? MessageInputPanelComponent.View { return { [weak inputPanelView] in inputPanelView?.activateInput() diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index ebecedc9a6..721e2e1d4d 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -4750,7 +4750,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro let canRemove = false - let exceptionController = notificationPeerExceptionController(context: context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, peer: EnginePeer(peer), threadId: threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, edit: true, updatePeerSound: { peerId, sound in + let exceptionController = notificationPeerExceptionController(context: context, updatedPresentationData: strongSelf.controller?.updatedPresentationData, peer: EnginePeer(peer), threadId: threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, defaultStoriesSound: globalSettings.privateChats.storySettings.sound, edit: true, updatePeerSound: { peerId, sound in let _ = (updatePeerSound(peer.id, sound) |> deliverOnMainQueue).start(next: { _ in })