This commit is contained in:
Ali 2023-06-30 02:38:24 +02:00
parent 7f8ef83baf
commit 2e83cef3f7
24 changed files with 1074 additions and 257 deletions

View File

@ -723,17 +723,18 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) |> deliverOnMainQueue return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) |> deliverOnMainQueue
} }
let updatePeerStoryNotifications: (PeerId, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = { peerId, storyNotifications in let updatePeerStoriesMuted: (PeerId, PeerStoryNotificationSettings.Mute) -> Signal<Void, NoError> = {
var isMuted: Bool? peerId, mute in
switch storyNotifications { return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, mute: mute) |> deliverOnMainQueue
case .default:
isMuted = nil
case .show:
isMuted = false
case .hide:
isMuted = true
} }
return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, isMuted: isMuted) |> deliverOnMainQueue
let updatePeerStoriesHideSender: (PeerId, PeerStoryNotificationSettings.HideSender) -> Signal<Void, NoError> = {
peerId, hideSender in
return context.engine.peers.updatePeerStoriesHideSenderSetting(peerId: peerId, hideSender: hideSender) |> deliverOnMainQueue
}
let updatePeerStorySound: (PeerId, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
return context.engine.peers.updatePeerStorySoundInteractive(peerId: peerId, sound: sound) |> deliverOnMainQueue
} }
let defaultSound: PeerMessageSound let defaultSound: PeerMessageSound
@ -769,8 +770,14 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|> deliverOnMainQueue).start(next: { _ in |> deliverOnMainQueue).start(next: { _ in
}) })
}, updatePeerStoryNotifications: { peerId, storyNotifications in }, updatePeerStoriesMuted: { peerId, mute in
let _ = (updatePeerStoryNotifications(peerId, storyNotifications) let _ = (updatePeerStoriesMuted(peerId, mute)
|> deliverOnMainQueue).start()
}, updatePeerStoriesHideSender: { peerId, hideSender in
let _ = (updatePeerStoriesHideSender(peerId, hideSender)
|> deliverOnMainQueue).start()
}, updatePeerStorySound: { peerId, sound in
let _ = (updatePeerStorySound(peerId, sound)
|> deliverOnMainQueue).start() |> deliverOnMainQueue).start()
}, removePeerFromExceptions: { }, removePeerFromExceptions: {
}, modifiedPeer: { }, modifiedPeer: {

View File

@ -2581,9 +2581,10 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
} }
let _ = (self.context.engine.data.get( let _ = (self.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peer.id) TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peer.id),
TelegramEngine.EngineData.Item.NotificationSettings.Global()
) )
|> deliverOnMainQueue).start(next: { [weak self] notificationSettings in |> deliverOnMainQueue).start(next: { [weak self] notificationSettings, globalSettings in
guard let self else { guard let self else {
return return
} }
@ -2639,7 +2640,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}) })
}))) })))
let isMuted = notificationSettings.storiesMuted == true let isMuted = resolvedAreStoriesMuted(globalSettings: globalSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: notificationSettings._asNotificationSettings())
items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify" : "Don't Notify", icon: { theme in items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify" : "Don't Notify", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) return generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, f in }, action: { [weak self] _, f in

View File

@ -3843,6 +3843,10 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
} }
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let item = self.item else {
return nil
}
if let compoundTextButtonNode = self.compoundTextButtonNode, let compoundHighlightingNode = self.compoundHighlightingNode, compoundHighlightingNode.alpha != 0.0 { if let compoundTextButtonNode = self.compoundTextButtonNode, let compoundHighlightingNode = self.compoundHighlightingNode, compoundHighlightingNode.alpha != 0.0 {
let localPoint = self.view.convert(point, to: compoundHighlightingNode.view) let localPoint = self.view.convert(point, to: compoundHighlightingNode.view)
var matches = false var matches = false
@ -3857,9 +3861,12 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
} }
} }
if let _ = item.interaction.inlineNavigationLocation {
} else {
if let avatarStoryIndicatorView = self.avatarStoryIndicator?.view, let result = avatarStoryIndicatorView.hitTest(self.view.convert(point, to: avatarStoryIndicatorView), with: event) { if let avatarStoryIndicatorView = self.avatarStoryIndicator?.view, let result = avatarStoryIndicatorView.hitTest(self.view.convert(point, to: avatarStoryIndicatorView), with: event) {
return result return result
} }
}
return super.hitTest(point, with: event) return super.hitTest(point, with: event)
} }

View File

@ -19,9 +19,14 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId), TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.AreVoiceCallsAvailable(id: peerId), TelegramEngine.EngineData.Item.Peer.AreVoiceCallsAvailable(id: peerId),
TelegramEngine.EngineData.Item.Peer.AreVideoCallsAvailable(id: peerId), TelegramEngine.EngineData.Item.Peer.AreVideoCallsAvailable(id: peerId),
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peerId) TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peerId),
TelegramEngine.EngineData.Item.NotificationSettings.Global()
) )
|> map { [weak contactsController] peer, areVoiceCallsAvailable, areVideoCallsAvailable, notificationSettings -> [ContextMenuItem] in |> map { [weak contactsController] peer, areVoiceCallsAvailable, areVideoCallsAvailable, notificationSettings, globalSettings -> [ContextMenuItem] in
guard let peer else {
return []
}
var items: [ContextMenuItem] = [] var items: [ContextMenuItem] = []
if isStories { if isStories {
@ -42,7 +47,8 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
}) })
}))) })))
let isMuted = notificationSettings.storiesMuted == true let isMuted = resolvedAreStoriesMuted(globalSettings: globalSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: notificationSettings._asNotificationSettings())
items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify" : "Don't Notify", icon: { theme in items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify" : "Don't Notify", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) return generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor)
}, action: { _, f in }, action: { _, f in
@ -50,7 +56,7 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
let _ = context.engine.peers.togglePeerStoriesMuted(peerId: peerId).start() let _ = context.engine.peers.togglePeerStoriesMuted(peerId: peerId).start()
if let peer { do {
let iconColor = UIColor.white let iconColor = UIColor.white
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
if isMuted { if isMuted {
@ -96,7 +102,7 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
return return
} }
if let peer { do {
let location = CGRect(origin: CGPoint(x: sourceFrame.midX, y: sourceFrame.minY + 1.0), size: CGSize()) let location = CGRect(origin: CGPoint(x: sourceFrame.midX, y: sourceFrame.minY + 1.0), size: CGSize())
let tooltipController = TooltipScreen( let tooltipController = TooltipScreen(
context: context, context: context,

View File

@ -62,8 +62,16 @@ private final class NotificationExceptionState : Equatable {
return NotificationExceptionState(mode: mode.withUpdatedPeerDisplayPreviews(peer, displayPreviews), isSearchMode: isSearchMode, revealedPeerId: self.revealedPeerId, editing: self.editing) return NotificationExceptionState(mode: mode.withUpdatedPeerDisplayPreviews(peer, displayPreviews), isSearchMode: isSearchMode, revealedPeerId: self.revealedPeerId, editing: self.editing)
} }
func withUpdatedPeerStoryNotifications(_ peer: EnginePeer, _ storyNotifications: PeerNotificationDisplayPreviews) -> NotificationExceptionState { func withUpdatedPeerStoriesMuted(_ peer: EnginePeer, _ mute: PeerStoryNotificationSettings.Mute) -> NotificationExceptionState {
return NotificationExceptionState(mode: mode.withUpdatedPeerStoryNotifications(peer, storyNotifications), isSearchMode: isSearchMode, revealedPeerId: self.revealedPeerId, editing: self.editing) return NotificationExceptionState(mode: mode.withUpdatedPeerStoriesMuted(peer, mute), isSearchMode: isSearchMode, revealedPeerId: self.revealedPeerId, editing: self.editing)
}
func withUpdatedPeerStoriesHideSender(_ peer: EnginePeer, _ hideSender: PeerStoryNotificationSettings.HideSender) -> NotificationExceptionState {
return NotificationExceptionState(mode: mode.withUpdatedPeerStoriesHideSender(peer, hideSender), isSearchMode: isSearchMode, revealedPeerId: self.revealedPeerId, editing: self.editing)
}
func withUpdatedPeerStorySound(_ peer: EnginePeer, _ sound: PeerMessageSound) -> NotificationExceptionState {
return NotificationExceptionState(mode: mode.withUpdatedPeerStorySound(peer, sound), isSearchMode: isSearchMode, revealedPeerId: self.revealedPeerId, editing: self.editing)
} }
static func == (lhs: NotificationExceptionState, rhs: NotificationExceptionState) -> Bool { static func == (lhs: NotificationExceptionState, rhs: NotificationExceptionState) -> Bool {
@ -584,17 +592,18 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: nil, displayPreviews: displayPreviews) |> deliverOnMainQueue return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: nil, displayPreviews: displayPreviews) |> deliverOnMainQueue
} }
let updatePeerStoryNotifications: (PeerId, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = { peerId, storyNotifications in let updatePeerStoriesMuted: (PeerId, PeerStoryNotificationSettings.Mute) -> Signal<Void, NoError> = {
var isMuted: Bool? peerId, mute in
switch storyNotifications { return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, mute: mute) |> deliverOnMainQueue
case .default:
isMuted = nil
case .show:
isMuted = false
case .hide:
isMuted = true
} }
return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, isMuted: isMuted) |> deliverOnMainQueue
let updatePeerStoriesHideSender: (PeerId, PeerStoryNotificationSettings.HideSender) -> Signal<Void, NoError> = {
peerId, hideSender in
return context.engine.peers.updatePeerStoriesHideSenderSetting(peerId: peerId, hideSender: hideSender) |> deliverOnMainQueue
}
let updatePeerStorySound: (PeerId, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
return context.engine.peers.updatePeerStorySoundInteractive(peerId: peerId, sound: sound) |> deliverOnMainQueue
} }
self.backgroundColor = presentationData.theme.list.blocksBackgroundColor self.backgroundColor = presentationData.theme.list.blocksBackgroundColor
@ -670,12 +679,32 @@ final class NotificationExceptionsControllerNode: ViewControllerTracingNode {
} }
updateNotificationsView({}) updateNotificationsView({})
}) })
}, updatePeerStoryNotifications: { peerId, displayPreviews in }, updatePeerStoriesMuted: { peerId, mute in
updateNotificationsDisposable.set(nil) updateNotificationsDisposable.set(nil)
_ = combineLatest(updatePeerStoryNotifications(peerId, displayPreviews), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in let _ = combineLatest(updatePeerStoriesMuted(peerId, mute), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer { if let peer = peer {
updateState { value in updateState { value in
return value.withUpdatedPeerStoryNotifications(peer, displayPreviews) return value.withUpdatedPeerStoriesMuted(peer, mute)
}
}
updateNotificationsView({})
})
}, updatePeerStoriesHideSender: { peerId, hideSender in
updateNotificationsDisposable.set(nil)
let _ = combineLatest(updatePeerStoriesHideSender(peerId, hideSender), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerStoriesHideSender(peer, hideSender)
}
}
updateNotificationsView({})
})
}, updatePeerStorySound: { peerId, sound in
updateNotificationsDisposable.set(nil)
let _ = combineLatest(updatePeerStorySound(peerId, sound), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerStorySound(peer, sound)
} }
} }
updateNotificationsView({}) updateNotificationsView({})

View File

@ -551,8 +551,19 @@ private func notificationsAndSoundsEntries(authorizationStatus: AccessType, warn
entries.append(.privateChats(presentationData.theme, presentationData.strings.Notifications_PrivateChats, !exceptions.users.isEmpty ? presentationData.strings.Notifications_CategoryExceptions(Int32(exceptions.users.peerIds.count)) : "", globalSettings.privateChats.enabled ? presentationData.strings.Notifications_On : presentationData.strings.Notifications_Off)) entries.append(.privateChats(presentationData.theme, presentationData.strings.Notifications_PrivateChats, !exceptions.users.isEmpty ? presentationData.strings.Notifications_CategoryExceptions(Int32(exceptions.users.peerIds.count)) : "", globalSettings.privateChats.enabled ? presentationData.strings.Notifications_On : presentationData.strings.Notifications_Off))
entries.append(.groupChats(presentationData.theme, presentationData.strings.Notifications_GroupChats, !exceptions.groups.isEmpty ? presentationData.strings.Notifications_CategoryExceptions(Int32(exceptions.groups.peerIds.count)) : "", globalSettings.groupChats.enabled ? presentationData.strings.Notifications_On : presentationData.strings.Notifications_Off)) entries.append(.groupChats(presentationData.theme, presentationData.strings.Notifications_GroupChats, !exceptions.groups.isEmpty ? presentationData.strings.Notifications_CategoryExceptions(Int32(exceptions.groups.peerIds.count)) : "", globalSettings.groupChats.enabled ? presentationData.strings.Notifications_On : presentationData.strings.Notifications_Off))
entries.append(.channels(presentationData.theme, presentationData.strings.Notifications_Channels, !exceptions.channels.isEmpty ? presentationData.strings.Notifications_CategoryExceptions(Int32(exceptions.channels.peerIds.count)) : "", globalSettings.channels.enabled ? presentationData.strings.Notifications_On : presentationData.strings.Notifications_Off)) entries.append(.channels(presentationData.theme, presentationData.strings.Notifications_Channels, !exceptions.channels.isEmpty ? presentationData.strings.Notifications_CategoryExceptions(Int32(exceptions.channels.peerIds.count)) : "", globalSettings.channels.enabled ? presentationData.strings.Notifications_On : presentationData.strings.Notifications_Off))
//TODO:localize //TODO:localize
entries.append(.stories(presentationData.theme, "Stories", !exceptions.stories.isEmpty ? presentationData.strings.Notifications_CategoryExceptions(Int32(exceptions.stories.peerIds.count)) : "", globalSettings.privateChats.storiesMuted != true ? presentationData.strings.Notifications_On : presentationData.strings.Notifications_Off)) let storiesValue: String
switch globalSettings.privateChats.storySettings.mute {
case .default:
storiesValue = "Top 5"
case .muted:
storiesValue = presentationData.strings.Notifications_Off
case .unmuted:
storiesValue = presentationData.strings.Notifications_On
}
entries.append(.stories(presentationData.theme, "Stories", !exceptions.stories.isEmpty ? presentationData.strings.Notifications_CategoryExceptions(Int32(exceptions.stories.peerIds.count)) : "", storiesValue))
entries.append(.inAppHeader(presentationData.theme, presentationData.strings.Notifications_InAppNotifications.uppercased())) entries.append(.inAppHeader(presentationData.theme, presentationData.strings.Notifications_InAppNotifications.uppercased()))
entries.append(.inAppSounds(presentationData.theme, presentationData.strings.Notifications_InAppNotificationsSounds, inAppSettings.playSounds)) entries.append(.inAppSounds(presentationData.theme, presentationData.strings.Notifications_InAppNotificationsSounds, inAppSettings.playSounds))
@ -730,6 +741,8 @@ public func notificationsAndSoundsController(context: AccountContext, exceptions
let exceptionsSignal = Signal<NotificationExceptionsList?, NoError>.single(exceptionsList) |> then(context.engine.peers.notificationExceptionsList() |> map(Optional.init)) let exceptionsSignal = Signal<NotificationExceptionsList?, NoError>.single(exceptionsList) |> then(context.engine.peers.notificationExceptionsList() |> map(Optional.init))
let defaultStorySettings = PeerStoryNotificationSettings.default
notificationExceptions.set(exceptionsSignal |> map { list -> (NotificationExceptionMode, NotificationExceptionMode, NotificationExceptionMode, NotificationExceptionMode) in notificationExceptions.set(exceptionsSignal |> map { list -> (NotificationExceptionMode, NotificationExceptionMode, NotificationExceptionMode, NotificationExceptionMode) in
var users:[PeerId : NotificationExceptionWrapper] = [:] var users:[PeerId : NotificationExceptionWrapper] = [:]
var groups: [PeerId : NotificationExceptionWrapper] = [:] var groups: [PeerId : NotificationExceptionWrapper] = [:]
@ -738,7 +751,7 @@ public func notificationsAndSoundsController(context: AccountContext, exceptions
if let list = list { if let list = list {
for (key, value) in list.settings { for (key, value) in list.settings {
if let peer = list.peers[key], !peer.debugDisplayTitle.isEmpty, peer.id != context.account.peerId { if let peer = list.peers[key], !peer.debugDisplayTitle.isEmpty, peer.id != context.account.peerId {
if value.storiesMuted != nil { if value.storySettings != defaultStorySettings {
stories[key] = NotificationExceptionWrapper(settings: value, peer: EnginePeer(peer)) stories[key] = NotificationExceptionWrapper(settings: value, peer: EnginePeer(peer))
} }

View File

@ -37,6 +37,7 @@ private final class NotificationsPeerCategoryControllerArguments {
let soundSelectionDisposable: MetaDisposable let soundSelectionDisposable: MetaDisposable
let updateEnabled: (Bool) -> Void let updateEnabled: (Bool) -> Void
let updateEnabledImportant: (Bool) -> Void
let updatePreviews: (Bool) -> Void let updatePreviews: (Bool) -> Void
let openSound: (PeerMessageSound) -> Void let openSound: (PeerMessageSound) -> Void
@ -49,11 +50,12 @@ private final class NotificationsPeerCategoryControllerArguments {
let updatedExceptionMode: (NotificationExceptionMode) -> Void let updatedExceptionMode: (NotificationExceptionMode) -> Void
init(context: AccountContext, soundSelectionDisposable: MetaDisposable, updateEnabled: @escaping (Bool) -> Void, updatePreviews: @escaping (Bool) -> Void, openSound: @escaping (PeerMessageSound) -> Void, addException: @escaping () -> Void, openException: @escaping (EnginePeer) -> Void, removeAllExceptions: @escaping () -> Void, updateRevealedPeerId: @escaping (EnginePeer.Id?) -> Void, removePeer: @escaping (EnginePeer) -> Void, updatedExceptionMode: @escaping (NotificationExceptionMode) -> Void) { init(context: AccountContext, soundSelectionDisposable: MetaDisposable, updateEnabled: @escaping (Bool) -> Void, updateEnabledImportant: @escaping (Bool) -> Void, updatePreviews: @escaping (Bool) -> Void, openSound: @escaping (PeerMessageSound) -> Void, addException: @escaping () -> Void, openException: @escaping (EnginePeer) -> Void, removeAllExceptions: @escaping () -> Void, updateRevealedPeerId: @escaping (EnginePeer.Id?) -> Void, removePeer: @escaping (EnginePeer) -> Void, updatedExceptionMode: @escaping (NotificationExceptionMode) -> Void) {
self.context = context self.context = context
self.soundSelectionDisposable = soundSelectionDisposable self.soundSelectionDisposable = soundSelectionDisposable
self.updateEnabled = updateEnabled self.updateEnabled = updateEnabled
self.updateEnabledImportant = updateEnabledImportant
self.updatePreviews = updatePreviews self.updatePreviews = updatePreviews
self.openSound = openSound self.openSound = openSound
@ -90,6 +92,8 @@ public enum NotificationsPeerCategoryEntryTag: ItemListItemTag {
private enum NotificationsPeerCategoryEntry: ItemListNodeEntry { private enum NotificationsPeerCategoryEntry: ItemListNodeEntry {
case enable(PresentationTheme, String, Bool) case enable(PresentationTheme, String, Bool)
case enableImportant(PresentationTheme, String, Bool)
case importantInfo(PresentationTheme, String)
case optionsHeader(PresentationTheme, String) case optionsHeader(PresentationTheme, String)
case previews(PresentationTheme, String, Bool) case previews(PresentationTheme, String, Bool)
case sound(PresentationTheme, String, String, PeerMessageSound) case sound(PresentationTheme, String, String, PeerMessageSound)
@ -101,7 +105,7 @@ private enum NotificationsPeerCategoryEntry: ItemListNodeEntry {
var section: ItemListSectionId { var section: ItemListSectionId {
switch self { switch self {
case .enable: case .enable, .enableImportant, .importantInfo:
return NotificationsPeerCategorySection.enable.rawValue return NotificationsPeerCategorySection.enable.rawValue
case .optionsHeader, .previews, .sound: case .optionsHeader, .previews, .sound:
return NotificationsPeerCategorySection.options.rawValue return NotificationsPeerCategorySection.options.rawValue
@ -114,18 +118,22 @@ private enum NotificationsPeerCategoryEntry: ItemListNodeEntry {
switch self { switch self {
case .enable: case .enable:
return 0 return 0
case .optionsHeader: case .enableImportant:
return 1 return 1
case .previews: case .importantInfo:
return 2 return 2
case .sound: case .optionsHeader:
return 3 return 3
case .exceptionsHeader: case .previews:
return 4 return 4
case .addException: case .sound:
return 5 return 5
case .exceptionsHeader:
return 6
case .addException:
return 7
case let .exception(index, _, _, _, _, _, _, _, _, _): case let .exception(index, _, _, _, _, _, _, _, _, _):
return 6 + index return 8 + index
case .removeAllExceptions: case .removeAllExceptions:
return 100000 return 100000
} }
@ -152,6 +160,18 @@ private enum NotificationsPeerCategoryEntry: ItemListNodeEntry {
} else { } else {
return false return false
} }
case let .enableImportant(lhsTheme, lhsText, lhsValue):
if case let .enableImportant(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .importantInfo(lhsTheme, lhsText):
if case let .importantInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .optionsHeader(lhsTheme, lhsText): case let .optionsHeader(lhsTheme, lhsText):
if case let .optionsHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText { if case let .optionsHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true return true
@ -209,6 +229,12 @@ private enum NotificationsPeerCategoryEntry: ItemListNodeEntry {
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateEnabled(updatedValue) arguments.updateEnabled(updatedValue)
}, tag: self.tag) }, tag: self.tag)
case let .enableImportant(_, text, value):
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateEnabledImportant(updatedValue)
}, tag: self.tag)
case let .importantInfo(_, text):
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
case let .optionsHeader(_, text): case let .optionsHeader(_, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .previews(_, text, value): case let .previews(_, text, value):
@ -266,7 +292,34 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor
} }
if case .stories = category { if case .stories = category {
entries.append(.enable(presentationData.theme, "Show All Notifications", notificationSettings.storiesMuted == nil || notificationSettings.storiesMuted == false)) var allEnabled = false
var importantEnabled = false
switch notificationSettings.storySettings.mute {
case .muted:
allEnabled = false
importantEnabled = false
case .unmuted:
allEnabled = true
importantEnabled = true
case .default:
allEnabled = false
importantEnabled = true
}
//TODO:localize
entries.append(.enable(presentationData.theme, "Show All Notifications", allEnabled))
if !allEnabled {
entries.append(.enableImportant(presentationData.theme, "Show Important Notifications", importantEnabled))
entries.append(.importantInfo(presentationData.theme, "Always on for top 5 contacts."))
}
if notificationSettings.enabled || !notificationExceptions.isEmpty {
entries.append(.optionsHeader(presentationData.theme, presentationData.strings.Notifications_Options.uppercased()))
entries.append(.previews(presentationData.theme, "Display Author Name", notificationSettings.storySettings.hideSender != .hide))
entries.append(.sound(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsSound, localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: filteredGlobalSound(notificationSettings.storySettings.sound)), filteredGlobalSound(notificationSettings.storySettings.sound)))
}
} else { } else {
entries.append(.enable(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsAlert, notificationSettings.enabled)) entries.append(.enable(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsAlert, notificationSettings.enabled))
@ -280,7 +333,6 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor
entries.append(.exceptionsHeader(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsExceptions.uppercased())) entries.append(.exceptionsHeader(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsExceptions.uppercased()))
entries.append(.addException(presentationData.theme, presentationData.strings.Notification_Exceptions_AddException)) entries.append(.addException(presentationData.theme, presentationData.strings.Notification_Exceptions_AddException))
let sortedExceptions = notificationExceptions.settings.sorted(by: { lhs, rhs in let sortedExceptions = notificationExceptions.settings.sorted(by: { lhs, rhs in
let lhsName = lhs.value.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) let lhsName = lhs.value.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
let rhsName = rhs.value.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder) let rhsName = rhs.value.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)
@ -312,11 +364,39 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor
var title: String var title: String
if case .stories = category { if case .stories = category {
if value.settings.storiesMuted == true { var muted = false
if value.settings.storySettings.mute == .muted {
muted = true
title = presentationData.strings.Notification_Exceptions_AlwaysOff title = presentationData.strings.Notification_Exceptions_AlwaysOff
} else { } else {
title = presentationData.strings.Notification_Exceptions_AlwaysOn title = presentationData.strings.Notification_Exceptions_AlwaysOn
} }
if !muted {
switch value.settings.storySettings.sound {
case .default:
break
default:
if !title.isEmpty {
title.append(", ")
}
title.append(presentationData.strings.Notification_Exceptions_SoundCustom)
}
switch value.settings.storySettings.hideSender {
case .default:
break
default:
if !title.isEmpty {
title += ", "
}
//TODO:localize
if case .show = value.settings.displayPreviews {
title += "Show Names"
} else {
title += "Hide Names"
}
}
}
} else { } else {
var muted = false var muted = false
switch value.settings.muteState { switch value.settings.muteState {
@ -427,8 +507,16 @@ private final class NotificationExceptionState : Equatable {
return NotificationExceptionState(mode: mode.withUpdatedPeerDisplayPreviews(peer, displayPreviews), revealedPeerId: self.revealedPeerId, editing: self.editing) return NotificationExceptionState(mode: mode.withUpdatedPeerDisplayPreviews(peer, displayPreviews), revealedPeerId: self.revealedPeerId, editing: self.editing)
} }
func withUpdatedPeerStoryNotifications(_ peer: EnginePeer, _ storyNotifications: PeerNotificationDisplayPreviews) -> NotificationExceptionState { func withUpdatedPeerStoriesMuted(_ peer: EnginePeer, _ mute: PeerStoryNotificationSettings.Mute) -> NotificationExceptionState {
return NotificationExceptionState(mode: mode.withUpdatedPeerStoryNotifications(peer, storyNotifications), revealedPeerId: self.revealedPeerId, editing: self.editing) return NotificationExceptionState(mode: mode.withUpdatedPeerStoriesMuted(peer, mute), revealedPeerId: self.revealedPeerId, editing: self.editing)
}
func withUpdatedPeerStoriesHideSender(_ peer: EnginePeer, _ hideSender: PeerStoryNotificationSettings.HideSender) -> NotificationExceptionState {
return NotificationExceptionState(mode: mode.withUpdatedPeerStoriesHideSender(peer, hideSender), revealedPeerId: self.revealedPeerId, editing: self.editing)
}
func withUpdatedPeerStorySound(_ peer: EnginePeer, _ sound: PeerMessageSound) -> NotificationExceptionState {
return NotificationExceptionState(mode: mode.withUpdatedPeerStorySound(peer, sound), revealedPeerId: self.revealedPeerId, editing: self.editing)
} }
static func == (lhs: NotificationExceptionState, rhs: NotificationExceptionState) -> Bool { static func == (lhs: NotificationExceptionState, rhs: NotificationExceptionState) -> Bool {
@ -470,17 +558,18 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: nil, displayPreviews: displayPreviews) |> deliverOnMainQueue return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: nil, displayPreviews: displayPreviews) |> deliverOnMainQueue
} }
let updatePeerStoryNotifications: (EnginePeer.Id, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = { peerId, storyNotifications in let updatePeerStoriesMuted: (EnginePeer.Id, PeerStoryNotificationSettings.Mute) -> Signal<Void, NoError> = {
var isMuted: Bool? peerId, mute in
switch storyNotifications { return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, mute: mute) |> deliverOnMainQueue
case .default:
isMuted = nil
case .show:
isMuted = false
case .hide:
isMuted = true
} }
return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, isMuted: isMuted) |> deliverOnMainQueue
let updatePeerStoriesHideSender: (EnginePeer.Id, PeerStoryNotificationSettings.HideSender) -> Signal<Void, NoError> = {
peerId, hideSender in
return context.engine.peers.updatePeerStoriesHideSenderSetting(peerId: peerId, hideSender: hideSender) |> deliverOnMainQueue
}
let updatePeerStorySound: (EnginePeer.Id, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
return context.engine.peers.updatePeerStorySoundInteractive(peerId: peerId, sound: sound) |> deliverOnMainQueue
} }
var peerIds: Set<EnginePeer.Id> = Set(mode.peerIds) var peerIds: Set<EnginePeer.Id> = Set(mode.peerIds)
@ -587,12 +676,32 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
} }
updateNotificationsView({}) updateNotificationsView({})
}) })
}, updatePeerStoryNotifications: { peerId, storyNotifications in }, updatePeerStoriesMuted: { peerId, mute in
updateNotificationsDisposable.set(nil) updateNotificationsDisposable.set(nil)
_ = combineLatest(updatePeerStoryNotifications(peerId, storyNotifications), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in let _ = combineLatest(updatePeerStoriesMuted(peerId, mute), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer { if let peer = peer {
updateState { value in updateState { value in
return value.withUpdatedPeerStoryNotifications(peer, storyNotifications) return value.withUpdatedPeerStoriesMuted(peer, mute)
}
}
updateNotificationsView({})
})
}, updatePeerStoriesHideSender: { peerId, hideSender in
updateNotificationsDisposable.set(nil)
let _ = combineLatest(updatePeerStoriesHideSender(peerId, hideSender), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerStoriesHideSender(peer, hideSender)
}
}
updateNotificationsView({})
})
}, updatePeerStorySound: { peerId, sound in
updateNotificationsDisposable.set(nil)
let _ = combineLatest(updatePeerStorySound(peerId, sound), context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) |> deliverOnMainQueue).start(next: { _, peer in
if let peer = peer {
updateState { value in
return value.withUpdatedPeerStorySound(peer, sound)
} }
} }
updateNotificationsView({}) updateNotificationsView({})
@ -608,7 +717,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
return return
} }
updateState { value in updateState { value in
return value.withUpdatedPeerStoryNotifications(peer, .default) return value.withUpdatedPeerStorySound(peer, .default).withUpdatedPeerStoriesMuted(peer, .default).withUpdatedPeerStoriesHideSender(peer, .default)
} }
updateNotificationsView({}) updateNotificationsView({})
}) })
@ -644,7 +753,18 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
case .channel: case .channel:
settings.channels.enabled = value settings.channels.enabled = value
case .stories: case .stories:
settings.privateChats.storiesMuted = !value settings.privateChats.storySettings.mute = value ? .unmuted : .default
}
return settings
}).start()
}, updateEnabledImportant: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
var settings = settings
switch category {
case .stories:
settings.privateChats.storySettings.mute = value ? .default : .muted
default:
break
} }
return settings return settings
}).start() }).start()
@ -659,7 +779,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
case .channel: case .channel:
settings.channels.displayPreviews = value settings.channels.displayPreviews = value
case .stories: case .stories:
break settings.privateChats.storySettings.hideSender = value ? .show : .hide
} }
return settings return settings
}).start() }).start()
@ -675,7 +795,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
case .channel: case .channel:
settings.channels.sound = value settings.channels.sound = value
case .stories: case .stories:
break settings.privateChats.storySettings.sound = value
} }
return settings return settings
}).start() }).start()
@ -722,7 +842,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
updateState { state in updateState { state in
var state = state var state = state
for value in values { for value in values {
state = state.withUpdatedPeerStoryNotifications(value.peer, .default) state = state.withUpdatedPeerStorySound(value.peer, .default).withUpdatedPeerStoriesMuted(value.peer, .default).withUpdatedPeerStoriesHideSender(value.peer, .default)
} }
return state return state
} }
@ -765,7 +885,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
|> deliverOnMainQueue).start(completed: { |> deliverOnMainQueue).start(completed: {
updateNotificationsDisposable.set(nil) updateNotificationsDisposable.set(nil)
updateState { value in updateState { value in
return value.withUpdatedPeerStoryNotifications(peer, .default) return value.withUpdatedPeerStorySound(peer, .default).withUpdatedPeerStoriesMuted(peer, .default).withUpdatedPeerStoriesHideSender(peer, .default)
} }
let _ = (context.engine.peers.removeCustomStoryNotificationSettings(peerIds: [peer.id]) let _ = (context.engine.peers.removeCustomStoryNotificationSettings(peerIds: [peer.id])
|> deliverOnMainQueue).start(completed: { |> deliverOnMainQueue).start(completed: {

View File

@ -6,12 +6,15 @@ import TelegramApi
extension TelegramPeerNotificationSettings { extension TelegramPeerNotificationSettings {
convenience init(apiSettings: Api.PeerNotifySettings) { convenience init(apiSettings: Api.PeerNotifySettings) {
switch apiSettings { switch apiSettings {
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, _, _, _, _): case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, storiesHideSender, storiesIosSound, _, storiesDesktopSound):
let sound: Api.NotificationSound? let sound: Api.NotificationSound?
let storiesSound: Api.NotificationSound?
#if os(iOS) #if os(iOS)
sound = iosSound sound = iosSound
storiesSound = storiesIosSound
#elseif os(macOS) #elseif os(macOS)
sound = desktopSound sound = desktopSound
storiesSound = storiesDesktopSound
#endif #endif
let muteState: PeerMuteState let muteState: PeerMuteState
@ -35,12 +38,25 @@ extension TelegramPeerNotificationSettings {
displayPreviews = .default displayPreviews = .default
} }
var storiesMutedValue: Bool? let storiesMutedValue: PeerStoryNotificationSettings.Mute
if let storiesMuted = storiesMuted { if let storiesMuted = storiesMuted {
storiesMutedValue = storiesMuted == .boolTrue storiesMutedValue = storiesMuted == .boolTrue ? .muted : .unmuted
} else {
storiesMutedValue = .default
} }
self.init(muteState: muteState, messageSound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault), displayPreviews: displayPreviews, storiesMuted: storiesMutedValue) var storiesHideSenderValue: PeerStoryNotificationSettings.HideSender
if let storiesHideSender = storiesHideSender {
storiesHideSenderValue = storiesHideSender == .boolTrue ? .hide : .show
} else {
storiesHideSenderValue = .default
}
self.init(muteState: muteState, messageSound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault), displayPreviews: displayPreviews, storySettings: PeerStoryNotificationSettings(
mute: storiesMutedValue,
hideSender: storiesHideSenderValue,
sound: PeerMessageSound(apiSound: storiesSound ?? .notificationSoundDefault)
))
} }
} }
} }

View File

@ -6,24 +6,48 @@ import TelegramApi
extension MessageNotificationSettings { extension MessageNotificationSettings {
init(apiSettings: Api.PeerNotifySettings) { init(apiSettings: Api.PeerNotifySettings) {
switch apiSettings { switch apiSettings {
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, _, _, _, _): case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, storiesHideSender, storiesIosSound, _, storiesDesktopSound):
let sound: Api.NotificationSound? let sound: Api.NotificationSound?
let storiesSound: Api.NotificationSound?
#if os(iOS) #if os(iOS)
sound = iosSound sound = iosSound
storiesSound = storiesIosSound
#elseif os(macOS) #elseif os(macOS)
sound = desktopSound sound = desktopSound
storiesSound = storiesDesktopSound
#endif #endif
let displayPreviews: Bool let displayPreviews: Bool
if let showPreviews = showPreviews, case .boolFalse = showPreviews { if let showPreviews = showPreviews, case .boolFalse = showPreviews {
displayPreviews = false displayPreviews = false
} else { } else {
displayPreviews = true displayPreviews = true
} }
var storiesMutedValue: Bool?
let storiesMutedValue: PeerStoryNotificationSettings.Mute
if let storiesMuted = storiesMuted { if let storiesMuted = storiesMuted {
storiesMutedValue = storiesMuted == .boolTrue storiesMutedValue = storiesMuted == .boolTrue ? .muted : .unmuted
} else {
storiesMutedValue = .default
} }
self = MessageNotificationSettings(enabled: muteUntil == 0, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault), storiesMuted: storiesMutedValue)
var storiesHideSenderValue: PeerStoryNotificationSettings.HideSender
if let storiesHideSender = storiesHideSender {
storiesHideSenderValue = storiesHideSender == .boolTrue ? .hide : .show
} else {
storiesHideSenderValue = .default
}
self = MessageNotificationSettings(
enabled: muteUntil == 0,
displayPreviews: displayPreviews,
sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault),
storySettings: PeerStoryNotificationSettings(
mute: storiesMutedValue,
hideSender: storiesHideSenderValue,
sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault)
)
)
} }
} }
} }

View File

@ -116,12 +116,15 @@ private func fetchedNotificationSettings(network: Network) -> Signal<GlobalNotif
|> map { chats, users, channels, contactsJoinedMuted in |> map { chats, users, channels, contactsJoinedMuted in
let chatsSettings: MessageNotificationSettings let chatsSettings: MessageNotificationSettings
switch chats { switch chats {
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, _, _, _, _): case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, storiesHideSender, storiesIosSound, _, storiesDesktopSound):
let sound: Api.NotificationSound? let sound: Api.NotificationSound?
let storiesSound: Api.NotificationSound?
#if os(iOS) #if os(iOS)
sound = iosSound sound = iosSound
storiesSound = storiesIosSound
#elseif os(macOS) #elseif os(macOS)
sound = desktopSound sound = desktopSound
storiesSound = storiesDesktopSound
#endif #endif
let enabled: Bool let enabled: Bool
@ -137,22 +140,43 @@ private func fetchedNotificationSettings(network: Network) -> Signal<GlobalNotif
displayPreviews = true displayPreviews = true
} }
var storiesMutedValue: Bool? let storiesMutedValue: PeerStoryNotificationSettings.Mute
if let storiesMuted = storiesMuted { if let storiesMuted = storiesMuted {
storiesMutedValue = storiesMuted == .boolTrue storiesMutedValue = storiesMuted == .boolTrue ? .muted : .unmuted
} else {
storiesMutedValue = .default
} }
chatsSettings = MessageNotificationSettings(enabled: enabled, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault), storiesMuted: storiesMutedValue) var storiesHideSenderValue: PeerStoryNotificationSettings.HideSender
if let storiesHideSender = storiesHideSender {
storiesHideSenderValue = storiesHideSender == .boolTrue ? .hide : .show
} else {
storiesHideSenderValue = .default
}
chatsSettings = MessageNotificationSettings(
enabled: enabled,
displayPreviews: displayPreviews,
sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault),
storySettings: PeerStoryNotificationSettings(
mute: storiesMutedValue,
hideSender: storiesHideSenderValue,
sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault)
)
)
} }
let userSettings: MessageNotificationSettings let userSettings: MessageNotificationSettings
switch users { switch users {
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, _, _, _, _): case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, storiesHideSender, storiesIosSound, _, storiesDesktopSound):
let sound: Api.NotificationSound? let sound: Api.NotificationSound?
let storiesSound: Api.NotificationSound?
#if os(iOS) #if os(iOS)
sound = iosSound sound = iosSound
storiesSound = storiesIosSound
#elseif os(macOS) #elseif os(macOS)
sound = desktopSound sound = desktopSound
storiesSound = storiesDesktopSound
#endif #endif
let enabled: Bool let enabled: Bool
@ -168,22 +192,43 @@ private func fetchedNotificationSettings(network: Network) -> Signal<GlobalNotif
displayPreviews = true displayPreviews = true
} }
var storiesMutedValue: Bool? let storiesMutedValue: PeerStoryNotificationSettings.Mute
if let storiesMuted = storiesMuted { if let storiesMuted = storiesMuted {
storiesMutedValue = storiesMuted == .boolTrue storiesMutedValue = storiesMuted == .boolTrue ? .muted : .unmuted
} else {
storiesMutedValue = .default
} }
userSettings = MessageNotificationSettings(enabled: enabled, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault), storiesMuted: storiesMutedValue) var storiesHideSenderValue: PeerStoryNotificationSettings.HideSender
if let storiesHideSender = storiesHideSender {
storiesHideSenderValue = storiesHideSender == .boolTrue ? .hide : .show
} else {
storiesHideSenderValue = .default
}
userSettings = MessageNotificationSettings(
enabled: enabled,
displayPreviews: displayPreviews,
sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault),
storySettings: PeerStoryNotificationSettings(
mute: storiesMutedValue,
hideSender: storiesHideSenderValue,
sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault)
)
)
} }
let channelSettings: MessageNotificationSettings let channelSettings: MessageNotificationSettings
switch channels { switch channels {
case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, _, _, _, _): case let .peerNotifySettings(_, showPreviews, _, muteUntil, iosSound, _, desktopSound, storiesMuted, storiesHideSender, storiesIosSound, _, storiesDesktopSound):
let sound: Api.NotificationSound? let sound: Api.NotificationSound?
let storiesSound: Api.NotificationSound?
#if os(iOS) #if os(iOS)
sound = iosSound sound = iosSound
storiesSound = storiesIosSound
#elseif os(macOS) #elseif os(macOS)
sound = desktopSound sound = desktopSound
storiesSound = storiesDesktopSound
#endif #endif
let enabled: Bool let enabled: Bool
@ -199,12 +244,30 @@ private func fetchedNotificationSettings(network: Network) -> Signal<GlobalNotif
displayPreviews = true displayPreviews = true
} }
var storiesMutedValue: Bool? let storiesMutedValue: PeerStoryNotificationSettings.Mute
if let storiesMuted = storiesMuted { if let storiesMuted = storiesMuted {
storiesMutedValue = storiesMuted == .boolTrue storiesMutedValue = storiesMuted == .boolTrue ? .muted : .unmuted
} else {
storiesMutedValue = .default
} }
channelSettings = MessageNotificationSettings(enabled: enabled, displayPreviews: displayPreviews, sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault), storiesMuted: storiesMutedValue) var storiesHideSenderValue: PeerStoryNotificationSettings.HideSender
if let storiesHideSender = storiesHideSender {
storiesHideSenderValue = storiesHideSender == .boolTrue ? .hide : .show
} else {
storiesHideSenderValue = .default
}
channelSettings = MessageNotificationSettings(
enabled: enabled,
displayPreviews: displayPreviews,
sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault),
storySettings: PeerStoryNotificationSettings(
mute: storiesMutedValue,
hideSender: storiesHideSenderValue,
sound: PeerMessageSound(apiSound: sound ?? .notificationSoundDefault)
)
)
} }
return GlobalNotificationSettingsSet(privateChats: userSettings, groupChats: chatsSettings, channels: channelSettings, contactsJoined: contactsJoinedMuted == .boolFalse) return GlobalNotificationSettingsSet(privateChats: userSettings, groupChats: chatsSettings, channels: channelSettings, contactsJoined: contactsJoinedMuted == .boolFalse)
@ -228,13 +291,38 @@ private func apiInputPeerNotifySettings(_ settings: MessageNotificationSettings)
flags |= (1 << 3) flags |= (1 << 3)
} }
var storiesMuted: Api.Bool? let storiesMuted: Api.Bool?
if let storiesMutedValue = settings.storiesMuted { switch settings.storySettings.mute {
case .default:
storiesMuted = nil
case .muted:
storiesMuted = .boolTrue
case .unmuted:
storiesMuted = .boolFalse
}
if storiesMuted != nil {
flags |= (1 << 6) flags |= (1 << 6)
storiesMuted = storiesMutedValue ? .boolTrue : .boolFalse
} }
return .inputPeerNotifySettings(flags: flags, showPreviews: settings.displayPreviews ? .boolTrue : .boolFalse, silent: nil, muteUntil: muteUntil, sound: sound, storiesMuted: storiesMuted, storiesHideSender: nil, storiesSound: nil) let storiesHideSender: Api.Bool?
switch settings.storySettings.hideSender {
case .default:
storiesHideSender = nil
case .hide:
storiesHideSender = .boolTrue
case .show:
storiesHideSender = .boolFalse
}
if storiesHideSender != nil {
flags |= (1 << 7)
}
let storiesSound: Api.NotificationSound? = settings.storySettings.sound.apiSound
if storiesSound != nil {
flags |= (1 << 8)
}
return .inputPeerNotifySettings(flags: flags, showPreviews: settings.displayPreviews ? .boolTrue : .boolFalse, silent: nil, muteUntil: muteUntil, sound: sound, storiesMuted: storiesMuted, storiesHideSender: storiesHideSender, storiesSound: storiesSound)
} }
private func pushedNotificationSettings(network: Network, settings: GlobalNotificationSettingsSet) -> Signal<Void, NoError> { private func pushedNotificationSettings(network: Network, settings: GlobalNotificationSettingsSet) -> Signal<Void, NoError> {

View File

@ -130,13 +130,39 @@ func pushPeerNotificationSettings(postbox: Postbox, network: Network, peerId: Pe
if sound != nil { if sound != nil {
flags |= (1 << 3) flags |= (1 << 3)
} }
var storiesMuted: Api.Bool?
if let storiesMutedValue = settings.storiesMuted { let storiesMuted: Api.Bool?
switch settings.storySettings.mute {
case .default:
storiesMuted = nil
case .muted:
storiesMuted = .boolTrue
case .unmuted:
storiesMuted = .boolFalse
}
if storiesMuted != nil {
flags |= (1 << 6) flags |= (1 << 6)
storiesMuted = storiesMutedValue ? .boolTrue : .boolFalse
} }
let inputSettings = Api.InputPeerNotifySettings.inputPeerNotifySettings(flags: flags, showPreviews: showPreviews, silent: nil, muteUntil: muteUntil, sound: sound, storiesMuted: storiesMuted, storiesHideSender: nil, storiesSound: nil) let storiesHideSender: Api.Bool?
switch settings.storySettings.hideSender {
case .default:
storiesHideSender = nil
case .hide:
storiesHideSender = .boolTrue
case .show:
storiesHideSender = .boolFalse
}
if storiesHideSender != nil {
flags |= (1 << 7)
}
let storiesSound: Api.NotificationSound? = settings.storySettings.sound.apiSound
if storiesSound != nil {
flags |= (1 << 8)
}
let inputSettings = Api.InputPeerNotifySettings.inputPeerNotifySettings(flags: flags, showPreviews: showPreviews, silent: nil, muteUntil: muteUntil, sound: sound, storiesMuted: storiesMuted, storiesHideSender: storiesHideSender, storiesSound: storiesSound)
return network.request(Api.functions.account.updateNotifySettings(peer: .inputNotifyForumTopic(peer: inputPeer, topMsgId: Int32(clamping: threadId)), settings: inputSettings)) return network.request(Api.functions.account.updateNotifySettings(peer: .inputNotifyForumTopic(peer: inputPeer, topMsgId: Int32(clamping: threadId)), settings: inputSettings))
|> `catch` { _ -> Signal<Api.Bool, NoError> in |> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse) return .single(.boolFalse)
@ -179,12 +205,39 @@ func pushPeerNotificationSettings(postbox: Postbox, network: Network, peerId: Pe
if sound != nil { if sound != nil {
flags |= (1 << 3) flags |= (1 << 3)
} }
var storiesMuted: Api.Bool?
if let storiesMutedValue = settings.storiesMuted { let storiesMuted: Api.Bool?
flags |= (1 << 6) switch settings.storySettings.mute {
storiesMuted = storiesMutedValue ? .boolTrue : .boolFalse case .default:
storiesMuted = nil
case .muted:
storiesMuted = .boolTrue
case .unmuted:
storiesMuted = .boolFalse
} }
let inputSettings = Api.InputPeerNotifySettings.inputPeerNotifySettings(flags: flags, showPreviews: showPreviews, silent: nil, muteUntil: muteUntil, sound: sound, storiesMuted: storiesMuted, storiesHideSender: nil, storiesSound: nil) if storiesMuted != nil {
flags |= (1 << 6)
}
let storiesHideSender: Api.Bool?
switch settings.storySettings.hideSender {
case .default:
storiesHideSender = nil
case .hide:
storiesHideSender = .boolTrue
case .show:
storiesHideSender = .boolFalse
}
if storiesHideSender != nil {
flags |= (1 << 7)
}
let storiesSound: Api.NotificationSound? = settings.storySettings.sound.apiSound
if storiesSound != nil {
flags |= (1 << 8)
}
let inputSettings = Api.InputPeerNotifySettings.inputPeerNotifySettings(flags: flags, showPreviews: showPreviews, silent: nil, muteUntil: muteUntil, sound: sound, storiesMuted: storiesMuted, storiesHideSender: storiesHideSender, storiesSound: storiesSound)
return network.request(Api.functions.account.updateNotifySettings(peer: .inputNotifyPeer(peer: inputPeer), settings: inputSettings)) return network.request(Api.functions.account.updateNotifySettings(peer: .inputNotifyPeer(peer: inputPeer), settings: inputSettings))
|> `catch` { _ -> Signal<Api.Bool, NoError> in |> `catch` { _ -> Signal<Api.Bool, NoError> in
return .single(.boolFalse) return .single(.boolFalse)

View File

@ -4,17 +4,17 @@ public struct MessageNotificationSettings: Codable, Equatable {
public var enabled: Bool public var enabled: Bool
public var displayPreviews: Bool public var displayPreviews: Bool
public var sound: PeerMessageSound public var sound: PeerMessageSound
public var storiesMuted: Bool? public var storySettings: PeerStoryNotificationSettings
public static var defaultSettings: MessageNotificationSettings { public static var defaultSettings: MessageNotificationSettings {
return MessageNotificationSettings(enabled: true, displayPreviews: true, sound: defaultCloudPeerNotificationSound, storiesMuted: nil) return MessageNotificationSettings(enabled: true, displayPreviews: true, sound: defaultCloudPeerNotificationSound, storySettings: PeerStoryNotificationSettings.default)
} }
public init(enabled: Bool, displayPreviews: Bool, sound: PeerMessageSound, storiesMuted: Bool?) { public init(enabled: Bool, displayPreviews: Bool, sound: PeerMessageSound, storySettings: PeerStoryNotificationSettings) {
self.enabled = enabled self.enabled = enabled
self.displayPreviews = displayPreviews self.displayPreviews = displayPreviews
self.sound = sound self.sound = sound
self.storiesMuted = storiesMuted self.storySettings = storySettings
} }
public init(from decoder: Decoder) throws { public init(from decoder: Decoder) throws {
@ -25,7 +25,7 @@ public struct MessageNotificationSettings: Codable, Equatable {
self.sound = try PeerMessageSound.decodeInline(container) self.sound = try PeerMessageSound.decodeInline(container)
self.storiesMuted = try? container.decodeIfPresent(Bool.self, forKey: "st") self.storySettings = try container.decodeIfPresent(PeerStoryNotificationSettings.self, forKey: "stor") ?? PeerStoryNotificationSettings(mute: .unmuted, hideSender: .show, sound: defaultCloudPeerNotificationSound)
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
@ -34,7 +34,7 @@ public struct MessageNotificationSettings: Codable, Equatable {
try container.encode((self.enabled ? 1 : 0) as Int32, forKey: "e") try container.encode((self.enabled ? 1 : 0) as Int32, forKey: "e")
try container.encode((self.displayPreviews ? 1 : 0) as Int32, forKey: "p") try container.encode((self.displayPreviews ? 1 : 0) as Int32, forKey: "p")
try self.sound.encodeInline(&container) try self.sound.encodeInline(&container)
try container.encodeIfPresent(self.storiesMuted, forKey: "st") try container.encode(self.storySettings, forKey: "stor")
} }
} }

View File

@ -388,14 +388,80 @@ public enum PeerNotificationDisplayPreviews: Equatable, Codable {
} }
} }
public struct PeerStoryNotificationSettings: Codable, Equatable {
public enum CodingError: Error {
case generic
}
public static var `default`: PeerStoryNotificationSettings {
return PeerStoryNotificationSettings(mute: .default, hideSender: .default, sound: .default)
}
private enum CodingKeys: String, CodingKey {
case mute = "m"
case hideSender = "hs"
case sound = "s"
}
public enum Mute: Int32, Codable {
case `default` = 0
case unmuted = 1
case muted = 2
}
public enum HideSender: Int32, Codable {
case `default` = 0
case hide = 1
case show = 2
}
public var mute: Mute
public var hideSender: HideSender
public var sound: PeerMessageSound
public init(
mute: Mute,
hideSender: HideSender,
sound: PeerMessageSound
) {
self.mute = mute
self.hideSender = hideSender
self.sound = sound
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
if let mute = Mute(rawValue: try container.decode(Int32.self, forKey: .mute)) {
self.mute = mute
} else {
throw CodingError.generic
}
if let hideSender = HideSender(rawValue: try container.decode(Int32.self, forKey: .hideSender)) {
self.hideSender = hideSender
} else {
throw CodingError.generic
}
self.sound = try container.decode(PeerMessageSound.self, forKey: .sound)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.mute.rawValue, forKey: .mute)
try container.encode(self.hideSender.rawValue, forKey: .hideSender)
try container.encode(self.sound, forKey: .sound)
}
}
public final class TelegramPeerNotificationSettings: PeerNotificationSettings, Codable, Equatable { public final class TelegramPeerNotificationSettings: PeerNotificationSettings, Codable, Equatable {
public let muteState: PeerMuteState public let muteState: PeerMuteState
public let messageSound: PeerMessageSound public let messageSound: PeerMessageSound
public let displayPreviews: PeerNotificationDisplayPreviews public let displayPreviews: PeerNotificationDisplayPreviews
public let storiesMuted: Bool? public let storySettings: PeerStoryNotificationSettings
public static var defaultSettings: TelegramPeerNotificationSettings { public static var defaultSettings: TelegramPeerNotificationSettings {
return TelegramPeerNotificationSettings(muteState: .unmuted, messageSound: .default, displayPreviews: .default, storiesMuted: nil) return TelegramPeerNotificationSettings(muteState: .unmuted, messageSound: .default, displayPreviews: .default, storySettings: PeerStoryNotificationSettings.default)
} }
public func isRemovedFromTotalUnreadCount(`default`: Bool) -> Bool { public func isRemovedFromTotalUnreadCount(`default`: Bool) -> Bool {
@ -417,18 +483,18 @@ public final class TelegramPeerNotificationSettings: PeerNotificationSettings, C
} }
} }
public init(muteState: PeerMuteState, messageSound: PeerMessageSound, displayPreviews: PeerNotificationDisplayPreviews, storiesMuted: Bool?) { public init(muteState: PeerMuteState, messageSound: PeerMessageSound, displayPreviews: PeerNotificationDisplayPreviews, storySettings: PeerStoryNotificationSettings) {
self.muteState = muteState self.muteState = muteState
self.messageSound = messageSound self.messageSound = messageSound
self.displayPreviews = displayPreviews self.displayPreviews = displayPreviews
self.storiesMuted = storiesMuted self.storySettings = storySettings
} }
public init(decoder: PostboxDecoder) { public init(decoder: PostboxDecoder) {
self.muteState = PeerMuteState.decodeInline(decoder) self.muteState = PeerMuteState.decodeInline(decoder)
self.messageSound = PeerMessageSound.decodeInline(decoder) self.messageSound = PeerMessageSound.decodeInline(decoder)
self.displayPreviews = PeerNotificationDisplayPreviews.decodeInline(decoder) self.displayPreviews = PeerNotificationDisplayPreviews.decodeInline(decoder)
self.storiesMuted = decoder.decodeOptionalBoolForKey("stm") self.storySettings = decoder.decode(PeerStoryNotificationSettings.self, forKey: "stor") ?? PeerStoryNotificationSettings.default
} }
public init(from decoder: Decoder) throws { public init(from decoder: Decoder) throws {
@ -437,7 +503,7 @@ public final class TelegramPeerNotificationSettings: PeerNotificationSettings, C
self.muteState = try container.decode(PeerMuteState.self, forKey: "muteState") self.muteState = try container.decode(PeerMuteState.self, forKey: "muteState")
self.messageSound = try container.decode(PeerMessageSound.self, forKey: "messageSound") self.messageSound = try container.decode(PeerMessageSound.self, forKey: "messageSound")
self.displayPreviews = try container.decode(PeerNotificationDisplayPreviews.self, forKey: "displayPreviews") self.displayPreviews = try container.decode(PeerNotificationDisplayPreviews.self, forKey: "displayPreviews")
self.storiesMuted = try? container.decodeIfPresent(Bool.self, forKey: "stm") self.storySettings = try container.decodeIfPresent(PeerStoryNotificationSettings.self, forKey: "stor") ?? PeerStoryNotificationSettings.default
} }
public func encode(to encoder: Encoder) throws { public func encode(to encoder: Encoder) throws {
@ -446,18 +512,14 @@ public final class TelegramPeerNotificationSettings: PeerNotificationSettings, C
try container.encode(self.muteState, forKey: "muteState") try container.encode(self.muteState, forKey: "muteState")
try container.encode(self.messageSound, forKey: "messageSound") try container.encode(self.messageSound, forKey: "messageSound")
try container.encode(self.displayPreviews, forKey: "displayPreviews") try container.encode(self.displayPreviews, forKey: "displayPreviews")
try container.encodeIfPresent(self.storiesMuted, forKey: "stm") try container.encode(self.storySettings, forKey: "stor")
} }
public func encode(_ encoder: PostboxEncoder) { public func encode(_ encoder: PostboxEncoder) {
self.muteState.encodeInline(encoder) self.muteState.encodeInline(encoder)
self.messageSound.encodeInline(encoder) self.messageSound.encodeInline(encoder)
self.displayPreviews.encodeInline(encoder) self.displayPreviews.encodeInline(encoder)
if let storiesMuted = self.storiesMuted { encoder.encode(self.storySettings, forKey: "stor")
encoder.encodeBool(storiesMuted, forKey: "stm")
} else {
encoder.encodeNil(forKey: "stm")
}
} }
public func isEqual(to: PeerNotificationSettings) -> Bool { public func isEqual(to: PeerNotificationSettings) -> Bool {
@ -469,22 +531,22 @@ public final class TelegramPeerNotificationSettings: PeerNotificationSettings, C
} }
public func withUpdatedMuteState(_ muteState: PeerMuteState) -> TelegramPeerNotificationSettings { public func withUpdatedMuteState(_ muteState: PeerMuteState) -> TelegramPeerNotificationSettings {
return TelegramPeerNotificationSettings(muteState: muteState, messageSound: self.messageSound, displayPreviews: self.displayPreviews, storiesMuted: self.storiesMuted) return TelegramPeerNotificationSettings(muteState: muteState, messageSound: self.messageSound, displayPreviews: self.displayPreviews, storySettings: self.storySettings)
} }
public func withUpdatedMessageSound(_ messageSound: PeerMessageSound) -> TelegramPeerNotificationSettings { public func withUpdatedMessageSound(_ messageSound: PeerMessageSound) -> TelegramPeerNotificationSettings {
return TelegramPeerNotificationSettings(muteState: self.muteState, messageSound: messageSound, displayPreviews: self.displayPreviews, storiesMuted: self.storiesMuted) return TelegramPeerNotificationSettings(muteState: self.muteState, messageSound: messageSound, displayPreviews: self.displayPreviews, storySettings: self.storySettings)
} }
public func withUpdatedDisplayPreviews(_ displayPreviews: PeerNotificationDisplayPreviews) -> TelegramPeerNotificationSettings { public func withUpdatedDisplayPreviews(_ displayPreviews: PeerNotificationDisplayPreviews) -> TelegramPeerNotificationSettings {
return TelegramPeerNotificationSettings(muteState: self.muteState, messageSound: self.messageSound, displayPreviews: displayPreviews, storiesMuted: self.storiesMuted) return TelegramPeerNotificationSettings(muteState: self.muteState, messageSound: self.messageSound, displayPreviews: displayPreviews, storySettings: self.storySettings)
} }
public func withUpdatedStoriesMuted(_ storiesMuted: Bool?) -> TelegramPeerNotificationSettings { public func withUpdatedStorySettings(_ storySettings: PeerStoryNotificationSettings) -> TelegramPeerNotificationSettings {
return TelegramPeerNotificationSettings(muteState: self.muteState, messageSound: self.messageSound, displayPreviews: self.displayPreviews, storiesMuted: storiesMuted) return TelegramPeerNotificationSettings(muteState: self.muteState, messageSound: self.messageSound, displayPreviews: self.displayPreviews, storySettings: storySettings)
} }
public static func ==(lhs: TelegramPeerNotificationSettings, rhs: TelegramPeerNotificationSettings) -> Bool { public static func ==(lhs: TelegramPeerNotificationSettings, rhs: TelegramPeerNotificationSettings) -> Bool {
return lhs.muteState == rhs.muteState && lhs.messageSound == rhs.messageSound && lhs.displayPreviews == rhs.displayPreviews && lhs.storiesMuted == rhs.storiesMuted return lhs.muteState == rhs.muteState && lhs.messageSound == rhs.messageSound && lhs.displayPreviews == rhs.displayPreviews && lhs.storySettings == rhs.storySettings
} }
} }

View File

@ -254,6 +254,44 @@ public extension TelegramEngine {
} }
} }
public func subscribe<
T0: TelegramEngineDataItem,
T1: TelegramEngineDataItem,
T2: TelegramEngineDataItem,
T3: TelegramEngineDataItem,
T4: TelegramEngineDataItem
>(
_ t0: T0,
_ t1: T1,
_ t2: T2,
_ t3: T3,
_ t4: T4
) -> Signal<
(
T0.Result,
T1.Result,
T2.Result,
T3.Result,
T4.Result
),
NoError> {
return self._subscribe(items: [
t0 as! AnyPostboxViewDataItem,
t1 as! AnyPostboxViewDataItem,
t2 as! AnyPostboxViewDataItem,
t3 as! AnyPostboxViewDataItem,
t4 as! AnyPostboxViewDataItem
])
|> map { results -> (T0.Result, T1.Result, T2.Result, T3.Result, T4.Result) in
return (
results[0] as! T0.Result,
results[1] as! T1.Result,
results[2] as! T2.Result,
results[3] as! T3.Result,
results[4] as! T4.Result
)
}
}
public func get< public func get<
T0: TelegramEngineDataItem, T0: TelegramEngineDataItem,
@ -308,5 +346,29 @@ public extension TelegramEngine {
NoError> { NoError> {
return self.subscribe(t0, t1, t2, t3) |> take(1) return self.subscribe(t0, t1, t2, t3) |> take(1)
} }
public func get<
T0: TelegramEngineDataItem,
T1: TelegramEngineDataItem,
T2: TelegramEngineDataItem,
T3: TelegramEngineDataItem,
T4: TelegramEngineDataItem
>(
_ t0: T0,
_ t1: T1,
_ t2: T2,
_ t3: T3,
_ t4: T4
) -> Signal<
(
T0.Result,
T1.Result,
T2.Result,
T3.Result,
T4.Result
),
NoError> {
return self.subscribe(t0, t1, t2, t3, t4) |> take(1)
}
} }
} }

View File

@ -62,6 +62,20 @@ func _internal_togglePeerMuted(account: Account, peerId: PeerId, threadId: Int64
} }
} }
public func resolvedAreStoriesMuted(globalSettings: GlobalNotificationSettingsSet, peer: Peer, peerSettings: TelegramPeerNotificationSettings?) -> Bool {
let defaultIsMuted = globalSettings.privateChats.storySettings.mute == .muted
switch peerSettings?.storySettings.mute {
case .none:
return defaultIsMuted
case .muted:
return true
case .unmuted:
return false
default:
return defaultIsMuted
}
}
func _internal_togglePeerStoriesMuted(account: Account, peerId: PeerId) -> Signal<Void, NoError> { func _internal_togglePeerStoriesMuted(account: Account, peerId: PeerId) -> Signal<Void, NoError> {
return account.postbox.transaction { transaction -> Void in return account.postbox.transaction { transaction -> Void in
guard let peer = transaction.getPeer(peerId) else { guard let peer = transaction.getPeer(peerId) else {
@ -82,12 +96,22 @@ func _internal_togglePeerStoriesMuted(account: Account, peerId: PeerId) -> Signa
} }
let updatedSettings: TelegramPeerNotificationSettings let updatedSettings: TelegramPeerNotificationSettings
if let previousStoriesMuted = previousSettings.storiesMuted { var storySettings = previousSettings.storySettings
updatedSettings = previousSettings.withUpdatedStoriesMuted(!previousStoriesMuted) switch previousSettings.storySettings.mute {
} else { case .default:
updatedSettings = previousSettings.withUpdatedStoriesMuted(true) let globalNotificationSettings = transaction.getPreferencesEntry(key: PreferencesKeys.globalNotifications)?.get(GlobalNotificationSettings.self) ?? GlobalNotificationSettings.defaultSettings
}
if resolvedAreStoriesMuted(globalSettings: globalNotificationSettings.effective, peer: peer, peerSettings: previousSettings) {
storySettings.mute = .unmuted
} else {
storySettings.mute = .muted
}
case .unmuted:
storySettings.mute = .muted
case .muted:
storySettings.mute = .unmuted
}
updatedSettings = previousSettings.withUpdatedStorySettings(storySettings)
transaction.updatePendingPeerNotificationSettings(peerId: notificationPeerId, settings: updatedSettings) transaction.updatePendingPeerNotificationSettings(peerId: notificationPeerId, settings: updatedSettings)
} }
} }
@ -213,13 +237,13 @@ func _internal_updatePeerDisplayPreviewsSetting(account: Account, transaction: T
} }
} }
func _internal_updatePeerStoriesMutedSetting(account: Account, peerId: PeerId, isMuted: Bool?) -> Signal<Void, NoError> { func _internal_updatePeerStoriesMutedSetting(account: Account, peerId: PeerId, mute: PeerStoryNotificationSettings.Mute) -> Signal<Void, NoError> {
return account.postbox.transaction { transaction -> Void in return account.postbox.transaction { transaction -> Void in
_internal_updatePeerStoriesMutedSetting(account: account, transaction: transaction, peerId: peerId, isMuted: isMuted) _internal_updatePeerStoriesMutedSetting(account: account, transaction: transaction, peerId: peerId, mute: mute)
} }
} }
func _internal_updatePeerStoriesMutedSetting(account: Account, transaction: Transaction, peerId: PeerId, isMuted: Bool?) { func _internal_updatePeerStoriesMutedSetting(account: Account, transaction: Transaction, peerId: PeerId, mute: PeerStoryNotificationSettings.Mute) {
if let peer = transaction.getPeer(peerId) { if let peer = transaction.getPeer(peerId) {
var notificationPeerId = peerId var notificationPeerId = peerId
if let associatedPeerId = peer.associatedPeerId { if let associatedPeerId = peer.associatedPeerId {
@ -234,7 +258,31 @@ func _internal_updatePeerStoriesMutedSetting(account: Account, transaction: Tran
previousSettings = TelegramPeerNotificationSettings.defaultSettings previousSettings = TelegramPeerNotificationSettings.defaultSettings
} }
let updatedSettings = previousSettings.withUpdatedStoriesMuted(isMuted) var storySettings = previousSettings.storySettings
storySettings.mute = mute
let updatedSettings = previousSettings.withUpdatedStorySettings(storySettings)
transaction.updatePendingPeerNotificationSettings(peerId: peerId, settings: updatedSettings)
}
}
func _internal_updatePeerStoriesHideSenderSetting(account: Account, transaction: Transaction, peerId: PeerId, hideSender: PeerStoryNotificationSettings.HideSender) {
if let peer = transaction.getPeer(peerId) {
var notificationPeerId = peerId
if let associatedPeerId = peer.associatedPeerId {
notificationPeerId = associatedPeerId
}
let currentSettings = transaction.getPeerNotificationSettings(id: notificationPeerId) as? TelegramPeerNotificationSettings
let previousSettings: TelegramPeerNotificationSettings
if let currentSettings = currentSettings {
previousSettings = currentSettings
} else {
previousSettings = TelegramPeerNotificationSettings.defaultSettings
}
var storySettings = previousSettings.storySettings
storySettings.hideSender = hideSender
let updatedSettings = previousSettings.withUpdatedStorySettings(storySettings)
transaction.updatePendingPeerNotificationSettings(peerId: peerId, settings: updatedSettings) transaction.updatePendingPeerNotificationSettings(peerId: peerId, settings: updatedSettings)
} }
} }
@ -279,3 +327,25 @@ func _internal_updatePeerNotificationSoundInteractive(account: Account, transact
} }
} }
} }
func _internal_updatePeerStoryNotificationSoundInteractive(account: Account, transaction: Transaction, peerId: PeerId, sound: PeerMessageSound) {
if let peer = transaction.getPeer(peerId) {
var notificationPeerId = peerId
if let associatedPeerId = peer.associatedPeerId {
notificationPeerId = associatedPeerId
}
let currentSettings = transaction.getPeerNotificationSettings(id: notificationPeerId) as? TelegramPeerNotificationSettings
let previousSettings: TelegramPeerNotificationSettings
if let currentSettings = currentSettings {
previousSettings = currentSettings
} else {
previousSettings = TelegramPeerNotificationSettings.defaultSettings
}
var storySettings = previousSettings.storySettings
storySettings.sound = sound
let updatedSettings = previousSettings.withUpdatedStorySettings(storySettings)
transaction.updatePendingPeerNotificationSettings(peerId: peerId, settings: updatedSettings)
}
}

View File

@ -19,7 +19,11 @@ public final class NotificationExceptionsList: Equatable {
} }
func _internal_notificationExceptionsList(postbox: Postbox, network: Network) -> Signal<NotificationExceptionsList, NoError> { func _internal_notificationExceptionsList(postbox: Postbox, network: Network) -> Signal<NotificationExceptionsList, NoError> {
return network.request(Api.functions.account.getNotifyExceptions(flags: 1 << 1, peer: nil)) var flags: Int32 = 0
flags |= 1 << 1
flags |= 1 << 2
return network.request(Api.functions.account.getNotifyExceptions(flags: flags, peer: nil))
|> retryRequest |> retryRequest
|> mapToSignal { result -> Signal<NotificationExceptionsList, NoError> in |> mapToSignal { result -> Signal<NotificationExceptionsList, NoError> in
return postbox.transaction { transaction -> NotificationExceptionsList in return postbox.transaction { transaction -> NotificationExceptionsList in

View File

@ -85,21 +85,23 @@ public enum EnginePeer: Equatable {
case hide case hide
} }
public typealias StorySettigs = PeerStoryNotificationSettings
public var muteState: MuteState public var muteState: MuteState
public var messageSound: MessageSound public var messageSound: MessageSound
public var displayPreviews: DisplayPreviews public var displayPreviews: DisplayPreviews
public var storiesMuted: Bool? public var storySettings: StorySettigs
public init( public init(
muteState: MuteState, muteState: MuteState,
messageSound: MessageSound, messageSound: MessageSound,
displayPreviews: DisplayPreviews, displayPreviews: DisplayPreviews,
storiesMuted: Bool? storySettings: StorySettigs
) { ) {
self.muteState = muteState self.muteState = muteState
self.messageSound = messageSound self.messageSound = messageSound
self.displayPreviews = displayPreviews self.displayPreviews = displayPreviews
self.storiesMuted = storiesMuted self.storySettings = storySettings
} }
} }
@ -219,13 +221,13 @@ public struct EngineGlobalNotificationSettings: Equatable {
public var enabled: Bool public var enabled: Bool
public var displayPreviews: Bool public var displayPreviews: Bool
public var sound: EnginePeer.NotificationSettings.MessageSound public var sound: EnginePeer.NotificationSettings.MessageSound
public var storiesMuted: Bool public var storySettings: EnginePeer.NotificationSettings.StorySettigs
public init(enabled: Bool, displayPreviews: Bool, sound: EnginePeer.NotificationSettings.MessageSound, storiesMuted: Bool) { public init(enabled: Bool, displayPreviews: Bool, sound: EnginePeer.NotificationSettings.MessageSound, storySettings: EnginePeer.NotificationSettings.StorySettigs) {
self.enabled = enabled self.enabled = enabled
self.displayPreviews = displayPreviews self.displayPreviews = displayPreviews
self.sound = sound self.sound = sound
self.storiesMuted = storiesMuted self.storySettings = storySettings
} }
} }
@ -333,7 +335,7 @@ public extension EnginePeer.NotificationSettings {
muteState: MuteState(notificationSettings.muteState), muteState: MuteState(notificationSettings.muteState),
messageSound: MessageSound(notificationSettings.messageSound), messageSound: MessageSound(notificationSettings.messageSound),
displayPreviews: DisplayPreviews(notificationSettings.displayPreviews), displayPreviews: DisplayPreviews(notificationSettings.displayPreviews),
storiesMuted: notificationSettings.storiesMuted storySettings: notificationSettings.storySettings
) )
} }
@ -342,7 +344,7 @@ public extension EnginePeer.NotificationSettings {
muteState: self.muteState._asMuteState(), muteState: self.muteState._asMuteState(),
messageSound: self.messageSound._asMessageSound(), messageSound: self.messageSound._asMessageSound(),
displayPreviews: self.displayPreviews._asDisplayPreviews(), displayPreviews: self.displayPreviews._asDisplayPreviews(),
storiesMuted: self.storiesMuted storySettings: self.storySettings
) )
} }
} }
@ -602,7 +604,7 @@ public extension EngineGlobalNotificationSettings.CategorySettings {
enabled: categorySettings.enabled, enabled: categorySettings.enabled,
displayPreviews: categorySettings.displayPreviews, displayPreviews: categorySettings.displayPreviews,
sound: EnginePeer.NotificationSettings.MessageSound(categorySettings.sound), sound: EnginePeer.NotificationSettings.MessageSound(categorySettings.sound),
storiesMuted: categorySettings.storiesMuted ?? false storySettings: categorySettings.storySettings
) )
} }
@ -611,7 +613,7 @@ public extension EngineGlobalNotificationSettings.CategorySettings {
enabled: self.enabled, enabled: self.enabled,
displayPreviews: self.displayPreviews, displayPreviews: self.displayPreviews,
sound: self.sound._asMessageSound(), sound: self.sound._asMessageSound(),
storiesMuted: self.storiesMuted storySettings: self.storySettings
) )
} }
} }
@ -625,4 +627,13 @@ public extension EngineGlobalNotificationSettings {
contactsJoined: globalNotificationSettings.contactsJoined contactsJoined: globalNotificationSettings.contactsJoined
) )
} }
func _asGlobalNotificationSettings() -> GlobalNotificationSettingsSet {
return GlobalNotificationSettingsSet(
privateChats: self.privateChats._asMessageNotificationSettings(),
groupChats: self.groupChats._asMessageNotificationSettings(),
channels: self.channels._asMessageNotificationSettings(),
contactsJoined: self.contactsJoined
)
}
} }

View File

@ -273,8 +273,20 @@ public extension TelegramEngine {
return _internal_updatePeerDisplayPreviewsSetting(account: self.account, peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) return _internal_updatePeerDisplayPreviewsSetting(account: self.account, peerId: peerId, threadId: threadId, displayPreviews: displayPreviews)
} }
public func updatePeerStoriesMutedSetting(peerId: PeerId, isMuted: Bool?) -> Signal<Void, NoError> { public func updatePeerStoriesMutedSetting(peerId: PeerId, mute: PeerStoryNotificationSettings.Mute) -> Signal<Void, NoError> {
return _internal_updatePeerStoriesMutedSetting(account: self.account, peerId: peerId, isMuted: isMuted) return _internal_updatePeerStoriesMutedSetting(account: self.account, peerId: peerId, mute: mute)
}
public func updatePeerStoriesHideSenderSetting(peerId: PeerId, hideSender: PeerStoryNotificationSettings.HideSender) -> Signal<Void, NoError> {
return self.account.postbox.transaction { transaction -> Void in
_internal_updatePeerStoriesHideSenderSetting(account: self.account, transaction: transaction, peerId: peerId, hideSender: hideSender)
}
}
public func updatePeerStorySoundInteractive(peerId: PeerId, sound: PeerMessageSound) -> Signal<Void, NoError> {
return self.account.postbox.transaction { transaction -> Void in
_internal_updatePeerStoryNotificationSoundInteractive(account: self.account, transaction: transaction, peerId: peerId, sound: sound)
}
} }
public func updatePeerNotificationSoundInteractive(peerId: PeerId, threadId: Int64?, sound: PeerMessageSound) -> Signal<Void, NoError> { public func updatePeerNotificationSoundInteractive(peerId: PeerId, threadId: Int64?, sound: PeerMessageSound) -> Signal<Void, NoError> {
@ -306,7 +318,9 @@ public extension TelegramEngine {
public func removeCustomStoryNotificationSettings(peerIds: [PeerId]) -> Signal<Never, NoError> { public func removeCustomStoryNotificationSettings(peerIds: [PeerId]) -> Signal<Never, NoError> {
return self.account.postbox.transaction { transaction -> Void in return self.account.postbox.transaction { transaction -> Void in
for peerId in peerIds { for peerId in peerIds {
_internal_updatePeerStoriesMutedSetting(account: self.account, transaction: transaction, peerId: peerId, isMuted: nil) _internal_updatePeerStoriesMutedSetting(account: self.account, transaction: transaction, peerId: peerId, mute: .default)
_internal_updatePeerStoriesHideSenderSetting(account: self.account, transaction: transaction, peerId: peerId, hideSender: .default)
_internal_updatePeerStoryNotificationSoundInteractive(account: self.account, transaction: transaction, peerId: peerId, sound: .default)
} }
} }
|> ignoreValues |> ignoreValues

View File

@ -496,7 +496,9 @@ public func threadNotificationExceptionsScreen(context: AccountContext, peerId:
} }
updated(stateValue.with({ $0 }).notificationExceptions) updated(stateValue.with({ $0 }).notificationExceptions)
}) })
}, updatePeerStoryNotifications: { _, _ in }, updatePeerStoriesMuted: { _, _ in
}, updatePeerStoriesHideSender: { _, _ in
}, updatePeerStorySound: { _, _ in
}, removePeerFromExceptions: { }, removePeerFromExceptions: {
let _ = context.engine.peers.removeCustomThreadNotificationSettings(peerId: peerId, threadIds: [item.threadId]).start() let _ = context.engine.peers.removeCustomThreadNotificationSettings(peerId: peerId, threadIds: [item.threadId]).start()
updateState { current in updateState { current in

View File

@ -123,7 +123,7 @@ public enum NotificationExceptionMode : Equatable {
case .default: case .default:
break break
default: default:
values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: .default, messageSound: sound, displayPreviews: .default, storiesMuted: nil), peer: peer, date: Date().timeIntervalSince1970) values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: .default, messageSound: sound, displayPreviews: .default, storySettings: .default), peer: peer, date: Date().timeIntervalSince1970)
} }
} }
return values return values
@ -161,7 +161,7 @@ public enum NotificationExceptionMode : Equatable {
case .default: case .default:
break break
default: default:
values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: muteState, messageSound: .default, displayPreviews: .default, storiesMuted: nil), peer: peer, date: Date().timeIntervalSince1970) values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: muteState, messageSound: .default, displayPreviews: .default, storySettings: .default), peer: peer, date: Date().timeIntervalSince1970)
} }
} }
return values return values
@ -215,7 +215,7 @@ public enum NotificationExceptionMode : Equatable {
case .default: case .default:
break break
default: default:
values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: .unmuted, messageSound: .default, displayPreviews: displayPreviews, storiesMuted: nil), peer: peer, date: Date().timeIntervalSince1970) values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: .unmuted, messageSound: .default, displayPreviews: displayPreviews, storySettings: .default), peer: peer, date: Date().timeIntervalSince1970)
} }
} }
return values return values
@ -233,32 +233,38 @@ public enum NotificationExceptionMode : Equatable {
} }
} }
public func withUpdatedPeerStoryNotifications(_ peer: EnginePeer, _ storyNotifications: PeerNotificationDisplayPreviews) -> NotificationExceptionMode { public func withUpdatedPeerStoriesMuted(_ peer: EnginePeer, _ mute: PeerStoryNotificationSettings.Mute) -> NotificationExceptionMode {
let apply:([EnginePeer.Id : NotificationExceptionWrapper], EnginePeer.Id, PeerNotificationDisplayPreviews) -> [EnginePeer.Id : NotificationExceptionWrapper] = { values, peerId, storyNotifications in let apply:([EnginePeer.Id : NotificationExceptionWrapper], EnginePeer.Id, PeerStoryNotificationSettings.Mute) -> [EnginePeer.Id : NotificationExceptionWrapper] = { values, peerId, mute in
let storiesMuted: Bool?
switch storyNotifications {
case .default:
storiesMuted = nil
case .show:
storiesMuted = false
case .hide:
storiesMuted = true
}
var values = values var values = values
if let value = values[peerId] { if let value = values[peerId] {
switch storyNotifications { switch mute {
case .default: case .default:
values.removeValue(forKey: peerId) switch value.settings.storySettings.mute {
case .default:
//values.removeValue(forKey: peerId)
break
default: default:
values[peerId] = value.updateSettings({$0.withUpdatedStoriesMuted(storiesMuted)}).withUpdatedDate(Date().timeIntervalSince1970) values[peerId] = value.updateSettings({
var updatedSettings = $0.storySettings
updatedSettings.mute = mute
return $0.withUpdatedStorySettings(updatedSettings)
}).withUpdatedDate(Date().timeIntervalSince1970)
}
default:
values[peerId] = value.updateSettings({
var updatedSettings = $0.storySettings
updatedSettings.mute = mute
return $0.withUpdatedStorySettings(updatedSettings)
}).withUpdatedDate(Date().timeIntervalSince1970)
} }
} else { } else {
switch storyNotifications { switch mute {
case .default: case .default:
break break
default: default:
values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: .unmuted, messageSound: .default, displayPreviews: .default, storiesMuted: storiesMuted), peer: peer, date: Date().timeIntervalSince1970) var updatedSettings = PeerStoryNotificationSettings.default
updatedSettings.mute = mute
values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: .unmuted, messageSound: .default, displayPreviews: .default, storySettings: updatedSettings), peer: peer, date: Date().timeIntervalSince1970)
} }
} }
return values return values
@ -266,7 +272,97 @@ public enum NotificationExceptionMode : Equatable {
switch self { switch self {
case let .stories(values): case let .stories(values):
return .stories(apply(values, peer.id, storyNotifications)) return .stories(apply(values, peer.id, mute))
default:
return self
}
}
public func withUpdatedPeerStoriesHideSender(_ peer: EnginePeer, _ hideSender: PeerStoryNotificationSettings.HideSender) -> NotificationExceptionMode {
let apply:([EnginePeer.Id : NotificationExceptionWrapper], EnginePeer.Id, PeerStoryNotificationSettings.HideSender) -> [EnginePeer.Id : NotificationExceptionWrapper] = { values, peerId, hideSender in
var values = values
if let value = values[peerId] {
switch hideSender {
case .default:
switch value.settings.storySettings.hideSender {
case .default:
//values.removeValue(forKey: peerId)
break
default:
values[peerId] = value.updateSettings({
var updatedSettings = $0.storySettings
updatedSettings.hideSender = hideSender
return $0.withUpdatedStorySettings(updatedSettings)
}).withUpdatedDate(Date().timeIntervalSince1970)
}
default:
values[peerId] = value.updateSettings({
var updatedSettings = $0.storySettings
updatedSettings.hideSender = hideSender
return $0.withUpdatedStorySettings(updatedSettings)
}).withUpdatedDate(Date().timeIntervalSince1970)
}
} else {
switch hideSender {
case .default:
break
default:
var updatedSettings = PeerStoryNotificationSettings.default
updatedSettings.hideSender = hideSender
values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: .unmuted, messageSound: .default, displayPreviews: .default, storySettings: updatedSettings), peer: peer, date: Date().timeIntervalSince1970)
}
}
return values
}
switch self {
case let .stories(values):
return .stories(apply(values, peer.id, hideSender))
default:
return self
}
}
public func withUpdatedPeerStorySound(_ peer: EnginePeer, _ sound: PeerMessageSound) -> NotificationExceptionMode {
let apply:([EnginePeer.Id : NotificationExceptionWrapper], EnginePeer.Id, PeerMessageSound) -> [EnginePeer.Id : NotificationExceptionWrapper] = { values, peerId, sound in
var values = values
if let value = values[peerId] {
switch sound {
case .default:
switch value.settings.storySettings.sound {
case .default:
//values.removeValue(forKey: peerId)
break
default:
values[peerId] = value.updateSettings({
var updatedSettings = $0.storySettings
updatedSettings.sound = sound
return $0.withUpdatedStorySettings(updatedSettings)
}).withUpdatedDate(Date().timeIntervalSince1970)
}
default:
values[peerId] = value.updateSettings({
var updatedSettings = $0.storySettings
updatedSettings.sound = sound
return $0.withUpdatedStorySettings(updatedSettings)
}).withUpdatedDate(Date().timeIntervalSince1970)
}
} else {
switch sound {
case .default:
break
default:
var updatedSettings = PeerStoryNotificationSettings.default
updatedSettings.sound = sound
values[peerId] = NotificationExceptionWrapper(settings: TelegramPeerNotificationSettings(muteState: .unmuted, messageSound: .default, displayPreviews: .default, storySettings: updatedSettings), peer: peer, date: Date().timeIntervalSince1970)
}
}
return values
}
switch self {
case let .stories(values):
return .stories(apply(values, peer.id, sound))
default: default:
return self return self
} }
@ -308,6 +404,7 @@ private enum NotificationPeerExceptionEntryId: Hashable {
case sound(PeerMessageSound.Id) case sound(PeerMessageSound.Id)
case switcherHeader case switcherHeader
case displayPreviews(NotificationPeerExceptionSwitcher) case displayPreviews(NotificationPeerExceptionSwitcher)
case showSender(NotificationPeerExceptionSwitcher)
case displayPreviewsHeader case displayPreviewsHeader
case storyNotifications(NotificationPeerExceptionSwitcher) case storyNotifications(NotificationPeerExceptionSwitcher)
case storyNotificationsHeader case storyNotificationsHeader
@ -326,19 +423,36 @@ private final class NotificationPeerExceptionArguments {
let selectSound: (PeerMessageSound) -> Void let selectSound: (PeerMessageSound) -> Void
let selectMode: (NotificationPeerExceptionSwitcher) -> Void let selectMode: (NotificationPeerExceptionSwitcher) -> Void
let selectDisplayPreviews: (NotificationPeerExceptionSwitcher) -> Void let selectDisplayPreviews: (NotificationPeerExceptionSwitcher) -> Void
let selectStoryNotifications: (NotificationPeerExceptionSwitcher) -> Void let selectStoriesMuted: (NotificationPeerExceptionSwitcher) -> Void
let selectHideStoriesSender: (NotificationPeerExceptionSwitcher) -> Void
let selectStorySound: (PeerMessageSound) -> Void
let removeFromExceptions: () -> Void let removeFromExceptions: () -> Void
let complete: () -> Void let complete: () -> Void
let cancel: () -> Void let cancel: () -> Void
let upload: () -> Void let upload: () -> Void
let deleteSound: (PeerMessageSound, String) -> Void let deleteSound: (PeerMessageSound, String) -> Void
init(account: Account, selectSound: @escaping(PeerMessageSound) -> Void, selectMode: @escaping(NotificationPeerExceptionSwitcher) -> Void, selectDisplayPreviews: @escaping (NotificationPeerExceptionSwitcher) -> Void, selectStoryNotifications: @escaping (NotificationPeerExceptionSwitcher) -> Void, removeFromExceptions: @escaping () -> Void, complete: @escaping()->Void, cancel: @escaping() -> Void, upload: @escaping () -> Void, deleteSound: @escaping (PeerMessageSound, String) -> Void) { init(
account: Account,
selectSound: @escaping(PeerMessageSound) -> Void,
selectMode: @escaping(NotificationPeerExceptionSwitcher) -> Void,
selectDisplayPreviews: @escaping (NotificationPeerExceptionSwitcher) -> Void,
selectStoriesMuted: @escaping (NotificationPeerExceptionSwitcher) -> Void,
selectHideStoriesSender: @escaping (NotificationPeerExceptionSwitcher) -> Void,
selectStorySound: @escaping (PeerMessageSound) -> Void,
removeFromExceptions: @escaping () -> Void,
complete: @escaping() -> Void,
cancel: @escaping() -> Void,
upload: @escaping () -> Void,
deleteSound: @escaping (PeerMessageSound, String) -> Void
) {
self.account = account self.account = account
self.selectSound = selectSound self.selectSound = selectSound
self.selectMode = selectMode self.selectMode = selectMode
self.selectDisplayPreviews = selectDisplayPreviews self.selectDisplayPreviews = selectDisplayPreviews
self.selectStoryNotifications = selectStoryNotifications self.selectStoriesMuted = selectStoriesMuted
self.selectHideStoriesSender = selectHideStoriesSender
self.selectStorySound = selectStorySound
self.removeFromExceptions = removeFromExceptions self.removeFromExceptions = removeFromExceptions
self.complete = complete self.complete = complete
self.cancel = cancel self.cancel = cancel
@ -355,6 +469,7 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
case switcher(index:Int32, theme: PresentationTheme, strings: PresentationStrings, mode: NotificationPeerExceptionSwitcher, selected: Bool) case switcher(index:Int32, theme: PresentationTheme, strings: PresentationStrings, mode: NotificationPeerExceptionSwitcher, selected: Bool)
case switcherHeader(index:Int32, theme: PresentationTheme, title: String) case switcherHeader(index:Int32, theme: PresentationTheme, title: String)
case displayPreviews(index:Int32, theme: PresentationTheme, strings: PresentationStrings, value: NotificationPeerExceptionSwitcher, selected: Bool) case displayPreviews(index:Int32, theme: PresentationTheme, strings: PresentationStrings, value: NotificationPeerExceptionSwitcher, selected: Bool)
case showSender(index:Int32, theme: PresentationTheme, strings: PresentationStrings, value: NotificationPeerExceptionSwitcher, selected: Bool)
case displayPreviewsHeader(index:Int32, theme: PresentationTheme, title: String) case displayPreviewsHeader(index:Int32, theme: PresentationTheme, title: String)
case storyNotifications(index:Int32, theme: PresentationTheme, strings: PresentationStrings, value: NotificationPeerExceptionSwitcher, selected: Bool) case storyNotifications(index:Int32, theme: PresentationTheme, strings: PresentationStrings, value: NotificationPeerExceptionSwitcher, selected: Bool)
case storyNotificationsHeader(index:Int32, theme: PresentationTheme, title: String) case storyNotificationsHeader(index:Int32, theme: PresentationTheme, title: String)
@ -379,6 +494,8 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
return index return index
case let .displayPreviews(index, _, _, _, _): case let .displayPreviews(index, _, _, _, _):
return index return index
case let .showSender(index, _, _, _, _):
return index
case let .storyNotificationsHeader(index, _, _): case let .storyNotificationsHeader(index, _, _):
return index return index
case let .storyNotifications(index, _, _, _, _): case let .storyNotifications(index, _, _, _, _):
@ -408,7 +525,7 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
return NotificationPeerExceptionSection.remove.rawValue return NotificationPeerExceptionSection.remove.rawValue
case .switcher, .switcherHeader: case .switcher, .switcherHeader:
return NotificationPeerExceptionSection.switcher.rawValue return NotificationPeerExceptionSection.switcher.rawValue
case .displayPreviews, .displayPreviewsHeader: case .displayPreviews, .displayPreviewsHeader, .showSender:
return NotificationPeerExceptionSection.displayPreviews.rawValue return NotificationPeerExceptionSection.displayPreviews.rawValue
case .storyNotifications, .storyNotificationsHeader: case .storyNotifications, .storyNotificationsHeader:
return NotificationPeerExceptionSection.storyNotifications.rawValue return NotificationPeerExceptionSection.storyNotifications.rawValue
@ -439,6 +556,8 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
return .displayPreviews(mode) return .displayPreviews(mode)
case .displayPreviewsHeader: case .displayPreviewsHeader:
return .displayPreviewsHeader return .displayPreviewsHeader
case let .showSender(_, _, _, mode, _):
return .showSender(mode)
case let .storyNotifications(_, _, _, mode, _): case let .storyNotifications(_, _, _, mode, _):
return .storyNotifications(mode) return .storyNotifications(mode)
case .storyNotificationsHeader: case .storyNotificationsHeader:
@ -497,6 +616,17 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
return ItemListCheckboxItem(presentationData: presentationData, title: title, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: { return ItemListCheckboxItem(presentationData: presentationData, title: title, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
arguments.selectDisplayPreviews(value) arguments.selectDisplayPreviews(value)
}) })
case let .showSender(_, _, strings, value, selected):
let title: String
switch value {
case .alwaysOn:
title = strings.Notification_Exceptions_MessagePreviewAlwaysOn
case .alwaysOff:
title = strings.Notification_Exceptions_MessagePreviewAlwaysOff
}
return ItemListCheckboxItem(presentationData: presentationData, title: title, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
arguments.selectHideStoriesSender(value)
})
case let .cloudHeader(_, text): case let .cloudHeader(_, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .cloudInfo(_, text): case let .cloudInfo(_, text):
@ -517,7 +647,7 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
title = strings.Notification_Exceptions_MessagePreviewAlwaysOff title = strings.Notification_Exceptions_MessagePreviewAlwaysOff
} }
return ItemListCheckboxItem(presentationData: presentationData, title: title, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: { return ItemListCheckboxItem(presentationData: presentationData, title: title, style: .left, checked: selected, zeroSeparatorInsets: false, sectionId: self.section, action: {
arguments.selectStoryNotifications(value) arguments.selectStoriesMuted(value)
}) })
case let .storyNotificationsHeader(_, _, text): case let .storyNotificationsHeader(_, _, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section) return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
@ -545,7 +675,7 @@ private enum NotificationPeerExceptionEntry: ItemListNodeEntry {
private func notificationPeerExceptionEntries(presentationData: PresentationData, peer: EnginePeer?, notificationSoundList: NotificationSoundList?, state: NotificationExceptionPeerState, isStories: Bool?) -> [NotificationPeerExceptionEntry] { private func notificationPeerExceptionEntries(presentationData: PresentationData, peer: EnginePeer?, notificationSoundList: NotificationSoundList?, state: NotificationExceptionPeerState, isStories: Bool?) -> [NotificationPeerExceptionEntry] {
let selectedSound = resolvedNotificationSound(sound: state.selectedSound, notificationSoundList: notificationSoundList) let selectedSound = resolvedNotificationSound(sound: isStories == true ? state.selectedStoriesSound : state.selectedSound, notificationSoundList: notificationSoundList)
var entries: [NotificationPeerExceptionEntry] = [] var entries: [NotificationPeerExceptionEntry] = []
@ -580,14 +710,31 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData
//TODO:localize //TODO:localize
entries.append(.storyNotificationsHeader(index: index, theme: presentationData.theme, title: "STORY NOTIFICATIONS")) entries.append(.storyNotificationsHeader(index: index, theme: presentationData.theme, title: "STORY NOTIFICATIONS"))
index += 1 index += 1
entries.append(.storyNotifications(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOn, selected: state.storyNotifications == .alwaysOn)) entries.append(.storyNotifications(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOn, selected: state.storiesMuted == .alwaysOn))
index += 1 index += 1
entries.append(.storyNotifications(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOff, selected: state.storyNotifications == .alwaysOff)) entries.append(.storyNotifications(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOff, selected: state.storiesMuted == .alwaysOff))
index += 1 index += 1
if state.storiesMuted != .alwaysOff {
entries.append(.displayPreviewsHeader(index: index, theme: presentationData.theme, title: "Display Author Name"))
index += 1
entries.append(.showSender(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOn, selected: state.storiesHideSender == .alwaysOn))
index += 1
entries.append(.showSender(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOff, selected: state.storiesHideSender == .alwaysOff))
index += 1
}
} }
} }
if isStories == nil || isStories == false { var displaySounds = true
if isStories == true {
if state.storiesMuted == .alwaysOff {
displaySounds = false
}
}
if displaySounds {
entries.append(.cloudHeader(index: index, text: presentationData.strings.Notifications_TelegramTones)) entries.append(.cloudHeader(index: index, text: presentationData.strings.Notifications_TelegramTones))
index += 1 index += 1
@ -650,7 +797,9 @@ private struct NotificationExceptionPeerState : Equatable {
var mode: NotificationPeerExceptionSwitcher var mode: NotificationPeerExceptionSwitcher
var defaultSound: PeerMessageSound var defaultSound: PeerMessageSound
var displayPreviews: NotificationPeerExceptionSwitcher var displayPreviews: NotificationPeerExceptionSwitcher
var storyNotifications: NotificationPeerExceptionSwitcher var storiesMuted: NotificationPeerExceptionSwitcher
var selectedStoriesSound: PeerMessageSound
var storiesHideSender: NotificationPeerExceptionSwitcher
var removedSounds: [PeerMessageSound] var removedSounds: [PeerMessageSound]
init(canRemove: Bool, notifications: TelegramPeerNotificationSettings? = nil) { init(canRemove: Bool, notifications: TelegramPeerNotificationSettings? = nil) {
@ -665,30 +814,64 @@ private struct NotificationExceptionPeerState : Equatable {
self.mode = .alwaysOn self.mode = .alwaysOn
} }
self.displayPreviews = notifications.displayPreviews == .hide ? .alwaysOff : .alwaysOn self.displayPreviews = notifications.displayPreviews == .hide ? .alwaysOff : .alwaysOn
self.storyNotifications = notifications.storiesMuted == true ? .alwaysOff : .alwaysOn self.storiesMuted = notifications.storySettings.mute == .muted ? .alwaysOff : .alwaysOn
self.selectedStoriesSound = notifications.storySettings.sound
self.storiesHideSender = notifications.storySettings.hideSender == .hide ? .alwaysOff : .alwaysOn
} else { } else {
self.selectedSound = .default self.selectedSound = .default
self.mode = .alwaysOn self.mode = .alwaysOn
self.displayPreviews = .alwaysOn self.displayPreviews = .alwaysOn
self.storyNotifications = .alwaysOn self.storiesMuted = PeerStoryNotificationSettings.default.mute == .muted ? .alwaysOff : .alwaysOn
self.selectedStoriesSound = PeerStoryNotificationSettings.default.sound
self.storiesHideSender = PeerStoryNotificationSettings.default.hideSender == .hide ? .alwaysOff : .alwaysOn
} }
self.defaultSound = .default self.defaultSound = .default
self.removedSounds = [] self.removedSounds = []
} }
init(canRemove: Bool, selectedSound: PeerMessageSound, mode: NotificationPeerExceptionSwitcher, defaultSound: PeerMessageSound, displayPreviews: NotificationPeerExceptionSwitcher, storyNotifications: NotificationPeerExceptionSwitcher, removedSounds: [PeerMessageSound]) { init(
canRemove: Bool,
selectedSound: PeerMessageSound,
mode: NotificationPeerExceptionSwitcher,
defaultSound: PeerMessageSound,
displayPreviews: NotificationPeerExceptionSwitcher,
storiesMuted: NotificationPeerExceptionSwitcher,
selectedStoriesSound: PeerMessageSound,
storiesHideSender: NotificationPeerExceptionSwitcher,
removedSounds: [PeerMessageSound]
) {
self.canRemove = canRemove self.canRemove = canRemove
self.selectedSound = selectedSound self.selectedSound = selectedSound
self.mode = mode self.mode = mode
self.defaultSound = defaultSound self.defaultSound = defaultSound
self.displayPreviews = displayPreviews self.displayPreviews = displayPreviews
self.storyNotifications = storyNotifications self.storiesMuted = storiesMuted
self.selectedStoriesSound = selectedStoriesSound
self.storiesHideSender = storiesHideSender
self.removedSounds = removedSounds self.removedSounds = removedSounds
} }
} }
public func notificationPeerExceptionController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peer: EnginePeer, customTitle: String? = nil, threadId: Int64?, isStories: Bool?, canRemove: Bool, defaultSound: PeerMessageSound, edit: Bool = false, updatePeerSound: @escaping(EnginePeer.Id, PeerMessageSound) -> Void, updatePeerNotificationInterval: @escaping(EnginePeer.Id, Int32?) -> Void, updatePeerDisplayPreviews: @escaping(EnginePeer.Id, PeerNotificationDisplayPreviews) -> Void, updatePeerStoryNotifications: @escaping(EnginePeer.Id, PeerNotificationDisplayPreviews) -> Void, removePeerFromExceptions: @escaping () -> Void, modifiedPeer: @escaping () -> Void) -> ViewController { public func notificationPeerExceptionController(
context: AccountContext,
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil,
peer: EnginePeer,
customTitle: String? = nil,
threadId: Int64?,
isStories: Bool?,
canRemove: Bool,
defaultSound: PeerMessageSound,
edit: Bool = false,
updatePeerSound: @escaping(EnginePeer.Id, PeerMessageSound) -> Void,
updatePeerNotificationInterval: @escaping(EnginePeer.Id, Int32?) -> Void,
updatePeerDisplayPreviews: @escaping(EnginePeer.Id, PeerNotificationDisplayPreviews) -> Void,
updatePeerStoriesMuted: @escaping(EnginePeer.Id, PeerStoryNotificationSettings.Mute) -> Void,
updatePeerStoriesHideSender: @escaping (EnginePeer.Id, PeerStoryNotificationSettings.HideSender) -> Void,
updatePeerStorySound: @escaping (EnginePeer.Id, PeerMessageSound) -> Void,
removePeerFromExceptions: @escaping () -> Void,
modifiedPeer: @escaping () -> Void
) -> ViewController {
let initialState = NotificationExceptionPeerState(canRemove: false) let initialState = NotificationExceptionPeerState(canRemove: false)
let statePromise = Promise(initialState) let statePromise = Promise(initialState)
let stateValue = Atomic(value: initialState) let stateValue = Atomic(value: initialState)
@ -706,6 +889,19 @@ public func notificationPeerExceptionController(context: AccountContext, updated
let soundActionDisposable = MetaDisposable() let soundActionDisposable = MetaDisposable()
let arguments = NotificationPeerExceptionArguments(account: context.account, selectSound: { sound in let arguments = NotificationPeerExceptionArguments(account: context.account, selectSound: { sound in
if isStories == true {
updateState { state in
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())
})
var state = state
state.selectedStoriesSound = sound
return state
}
} else {
updateState { state in updateState { state in
let _ = (context.engine.peers.notificationSoundList() let _ = (context.engine.peers.notificationSoundList()
|> take(1) |> take(1)
@ -717,6 +913,7 @@ public func notificationPeerExceptionController(context: AccountContext, updated
state.selectedSound = sound state.selectedSound = sound
return state return state
} }
}
}, selectMode: { mode in }, selectMode: { mode in
updateState { state in updateState { state in
var state = state var state = state
@ -729,10 +926,28 @@ public func notificationPeerExceptionController(context: AccountContext, updated
state.displayPreviews = value state.displayPreviews = value
return state return state
} }
}, selectStoryNotifications: { value in }, selectStoriesMuted: { value in
updateState { state in updateState { state in
var state = state var state = state
state.storyNotifications = value state.storiesMuted = value
return state
}
}, selectHideStoriesSender: { value in
updateState { state in
var state = state
state.storiesHideSender = value
return state
}
}, selectStorySound: { sound in
updateState { state in
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())
})
var state = state
state.selectedStoriesSound = sound
return state return state
} }
}, removeFromExceptions: { }, removeFromExceptions: {
@ -816,10 +1031,16 @@ public func notificationPeerExceptionController(context: AccountContext, updated
|> take(1) |> take(1)
|> deliverOnMainQueue).start(next: { notificationSoundList in |> deliverOnMainQueue).start(next: { notificationSoundList in
updateState { state in updateState { state in
if isStories == nil || isStories == false {
updatePeerSound(peer.id, resolvedNotificationSound(sound: state.selectedSound, notificationSoundList: notificationSoundList)) updatePeerSound(peer.id, resolvedNotificationSound(sound: state.selectedSound, notificationSoundList: notificationSoundList))
updatePeerNotificationInterval(peer.id, state.mode == .alwaysOn ? 0 : Int32.max) updatePeerNotificationInterval(peer.id, state.mode == .alwaysOn ? 0 : Int32.max)
updatePeerDisplayPreviews(peer.id, state.displayPreviews == .alwaysOn ? .show : .hide) updatePeerDisplayPreviews(peer.id, state.displayPreviews == .alwaysOn ? .show : .hide)
updatePeerStoryNotifications(peer.id, state.storyNotifications == .alwaysOn ? .show : .hide) }
if isStories == nil || isStories == true {
updatePeerStoriesMuted(peer.id, state.storiesMuted == .alwaysOn ? .unmuted : .muted)
updatePeerStoriesHideSender(peer.id, state.storiesHideSender == .alwaysOn ? .show : .hide)
updatePeerStorySound(peer.id, resolvedNotificationSound(sound: state.selectedStoriesSound, notificationSoundList: notificationSoundList))
}
return state return state
} }
}) })

View File

@ -100,10 +100,10 @@ public final class StoryContentContextImpl: StoryContentContext {
let additionalPeerData: StoryContentContextState.AdditionalPeerData let additionalPeerData: StoryContentContextState.AdditionalPeerData
if let cachedPeerDataView = views.views[PostboxViewKey.cachedPeerData(peerId: peerId)] as? CachedPeerDataView, let cachedUserData = cachedPeerDataView.cachedPeerData as? CachedUserData { if let cachedPeerDataView = views.views[PostboxViewKey.cachedPeerData(peerId: peerId)] as? CachedPeerDataView, let cachedUserData = cachedPeerDataView.cachedPeerData as? CachedUserData {
var isMuted = false var isMuted = false
if let notificationSettings = peerView.notificationSettings as? TelegramPeerNotificationSettings, let storiesMuted = notificationSettings.storiesMuted { if let notificationSettings = peerView.notificationSettings as? TelegramPeerNotificationSettings {
isMuted = storiesMuted isMuted = resolvedAreStoriesMuted(globalSettings: globalNotificationSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: notificationSettings)
} else { } else {
isMuted = globalNotificationSettings.privateChats.storiesMuted isMuted = resolvedAreStoriesMuted(globalSettings: globalNotificationSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: nil)
} }
additionalPeerData = StoryContentContextState.AdditionalPeerData(isMuted: isMuted, areVoiceMessagesAvailable: cachedUserData.voiceMessagesAvailable) additionalPeerData = StoryContentContextState.AdditionalPeerData(isMuted: isMuted, areVoiceMessagesAvailable: cachedUserData.voiceMessagesAvailable)
} else { } else {
@ -913,13 +913,12 @@ public final class SingleStoryContentContextImpl: StoryContentContext {
let (peer, areVoiceMessagesAvailable, notificationSettings, globalNotificationSettings) = data let (peer, areVoiceMessagesAvailable, notificationSettings, globalNotificationSettings) = data
let (item, peers) = itemAndPeers let (item, peers) = itemAndPeers
var isMuted = false guard let peer else {
if let storiesMuted = notificationSettings.storiesMuted { return
isMuted = storiesMuted
} else {
isMuted = globalNotificationSettings.privateChats.storiesMuted
} }
let isMuted = resolvedAreStoriesMuted(globalSettings: globalNotificationSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: notificationSettings._asNotificationSettings())
let additionalPeerData = StoryContentContextState.AdditionalPeerData( let additionalPeerData = StoryContentContextState.AdditionalPeerData(
isMuted: isMuted, isMuted: isMuted,
areVoiceMessagesAvailable: areVoiceMessagesAvailable areVoiceMessagesAvailable: areVoiceMessagesAvailable
@ -934,7 +933,7 @@ public final class SingleStoryContentContextImpl: StoryContentContext {
} }
} }
if let item, case let .item(itemValue) = item, let media = itemValue.media, let peer { if let item, case let .item(itemValue) = item, let media = itemValue.media {
let mappedItem = EngineStoryItem( let mappedItem = EngineStoryItem(
id: itemValue.id, id: itemValue.id,
timestamp: itemValue.timestamp, timestamp: itemValue.timestamp,
@ -1062,13 +1061,12 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
let (peer, areVoiceMessagesAvailable, notificationSettings, globalNotificationSettings) = data let (peer, areVoiceMessagesAvailable, notificationSettings, globalNotificationSettings) = data
var isMuted = false guard let peer else {
if let storiesMuted = notificationSettings.storiesMuted { return
isMuted = storiesMuted
} else {
isMuted = globalNotificationSettings.privateChats.storiesMuted
} }
let isMuted = resolvedAreStoriesMuted(globalSettings: globalNotificationSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: notificationSettings._asNotificationSettings())
let additionalPeerData = StoryContentContextState.AdditionalPeerData( let additionalPeerData = StoryContentContextState.AdditionalPeerData(
isMuted: isMuted, isMuted: isMuted,
areVoiceMessagesAvailable: areVoiceMessagesAvailable areVoiceMessagesAvailable: areVoiceMessagesAvailable
@ -1104,7 +1102,7 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
} }
let stateValue: StoryContentContextState let stateValue: StoryContentContextState
if let focusedIndex = focusedIndex, let peer = peer { if let focusedIndex = focusedIndex {
let item = state.items[focusedIndex] let item = state.items[focusedIndex]
self.focusedId = item.id self.focusedId = item.id
@ -1151,7 +1149,7 @@ public final class PeerStoryListContentContextImpl: StoryContentContext {
var resultResources: [EngineMediaResource.Id: StoryPreloadInfo] = [:] var resultResources: [EngineMediaResource.Id: StoryPreloadInfo] = [:]
var pollItems: [StoryKey] = [] var pollItems: [StoryKey] = []
if let peer, let focusedIndex, let slice = stateValue.slice { if let focusedIndex, let slice = stateValue.slice {
var possibleItems: [(EnginePeer, EngineStoryItem)] = [] var possibleItems: [(EnginePeer, EngineStoryItem)] = []
if peer.id == self.context.account.peerId { if peer.id == self.context.account.peerId {
pollItems.append(StoryKey(peerId: peer.id, id: slice.item.storyItem.id)) pollItems.append(StoryKey(peerId: peer.id, id: slice.item.storyItem.id))

View File

@ -138,7 +138,7 @@ final class StoryItemContentComponent: Component {
loopVideo: true, loopVideo: true,
enableSound: true, enableSound: true,
beginWithAmbientSound: environment.sharedState.useAmbientMode, beginWithAmbientSound: environment.sharedState.useAmbientMode,
useLargeThumbnail: true, useLargeThumbnail: false,
autoFetchFullSizeThumbnail: true, autoFetchFullSizeThumbnail: true,
tempFilePath: nil, tempFilePath: nil,
captureProtected: component.item.isForwardingDisabled, captureProtected: component.item.isForwardingDisabled,
@ -429,7 +429,7 @@ final class StoryItemContentComponent: Component {
userLocation: .other, userLocation: .other,
videoReference: .story(peer: peerReference, id: component.item.id, media: file), videoReference: .story(peer: peerReference, id: component.item.id, media: file),
onlyFullSize: false, onlyFullSize: false,
useLargeThumbnail: true, useLargeThumbnail: false,
synchronousLoad: synchronousLoad, synchronousLoad: synchronousLoad,
autoFetchFullSizeThumbnail: true, autoFetchFullSizeThumbnail: true,
overlayColor: nil, overlayColor: nil,

View File

@ -3145,8 +3145,11 @@ public final class StoryItemSetContainerComponent: Component {
guard let component = self.component else { guard let component = self.component else {
return return
} }
let _ = (component.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: component.slice.peer.id)) let _ = (component.context.engine.data.get(
|> deliverOnMainQueue).start(next: { [weak self] settings in TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: component.slice.peer.id),
TelegramEngine.EngineData.Item.NotificationSettings.Global()
)
|> deliverOnMainQueue).start(next: { [weak self] settings, globalSettings in
guard let self, let component = self.component, let controller = component.controller() else { guard let self, let component = self.component, let controller = component.controller() else {
return return
} }
@ -3161,7 +3164,8 @@ public final class StoryItemSetContainerComponent: Component {
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: component.theme) let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: component.theme)
var items: [ContextMenuItem] = [] var items: [ContextMenuItem] = []
let isMuted = settings.storiesMuted == true let isMuted = resolvedAreStoriesMuted(globalSettings: globalSettings._asGlobalNotificationSettings(), peer: component.slice.peer._asPeer(), peerSettings: settings._asNotificationSettings())
items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify" : "Don't Notify", icon: { theme in items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify" : "Don't Notify", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: component.slice.additionalPeerData.isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) return generateTintedImage(image: UIImage(bundleImageName: component.slice.additionalPeerData.isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, a in }, action: { [weak self] _, a in

View File

@ -4712,17 +4712,18 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) |> deliverOnMainQueue return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) |> deliverOnMainQueue
} }
let updatePeerStoryNotifications: (PeerId, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = { peerId, storyNotifications in let updatePeerStoriesMuted: (PeerId, PeerStoryNotificationSettings.Mute) -> Signal<Void, NoError> = {
var isMuted: Bool? peerId, mute in
switch storyNotifications { return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, mute: mute) |> deliverOnMainQueue
case .default:
isMuted = nil
case .show:
isMuted = false
case .hide:
isMuted = true
} }
return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, isMuted: isMuted) |> deliverOnMainQueue
let updatePeerStoriesHideSender: (PeerId, PeerStoryNotificationSettings.HideSender) -> Signal<Void, NoError> = {
peerId, hideSender in
return context.engine.peers.updatePeerStoriesHideSenderSetting(peerId: peerId, hideSender: hideSender) |> deliverOnMainQueue
}
let updatePeerStorySound: (PeerId, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
return context.engine.peers.updatePeerStorySoundInteractive(peerId: peerId, sound: sound) |> deliverOnMainQueue
} }
let mode: NotificationExceptionMode let mode: NotificationExceptionMode
@ -4775,11 +4776,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|> deliverOnMainQueue).start(next: { _ in |> deliverOnMainQueue).start(next: { _ in
}) })
}, updatePeerStoryNotifications: { peerId, storyNotifications in }, updatePeerStoriesMuted: { peerId, mute in
let _ = (updatePeerStoryNotifications(peerId, storyNotifications) let _ = (updatePeerStoriesMuted(peerId, mute)
|> deliverOnMainQueue).start(next: { _ in |> deliverOnMainQueue).start()
}, updatePeerStoriesHideSender: { peerId, hideSender in
}) let _ = (updatePeerStoriesHideSender(peerId, hideSender)
|> deliverOnMainQueue).start()
}, updatePeerStorySound: { peerId, sound in
let _ = (updatePeerStorySound(peer.id, sound)
|> deliverOnMainQueue).start()
}, removePeerFromExceptions: { }, removePeerFromExceptions: {
}, modifiedPeer: { }, modifiedPeer: {
}) })