Swiftgram/TelegramUI/NotificationsAndSounds.swift
2018-09-27 21:01:30 +01:00

552 lines
30 KiB
Swift

import Foundation
import Display
import SwiftSignalKit
import Postbox
import TelegramCore
private final class NotificationsAndSoundsArguments {
let account: Account
let presentController: (ViewController, ViewControllerPresentationArguments) -> Void
let soundSelectionDisposable: MetaDisposable
let updateMessageAlerts: (Bool) -> Void
let updateMessagePreviews: (Bool) -> Void
let updateMessageSound: (PeerMessageSound) -> Void
let updateGroupAlerts: (Bool) -> Void
let updateGroupPreviews: (Bool) -> Void
let updateGroupSound: (PeerMessageSound) -> Void
let updateInAppSounds: (Bool) -> Void
let updateInAppVibration: (Bool) -> Void
let updateInAppPreviews: (Bool) -> Void
let updateDisplayNameOnLockscreen: (Bool) -> Void
let updateTotalUnreadCountStyle: (Bool) -> Void
let updateTotalUnreadCountCategory: (Bool) -> Void
let resetNotifications: () -> Void
init(account: Account, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, soundSelectionDisposable: MetaDisposable, updateMessageAlerts: @escaping (Bool) -> Void, updateMessagePreviews: @escaping (Bool) -> Void, updateMessageSound: @escaping (PeerMessageSound) -> Void, updateGroupAlerts: @escaping (Bool) -> Void, updateGroupPreviews: @escaping (Bool) -> Void, updateGroupSound: @escaping (PeerMessageSound) -> Void, updateInAppSounds: @escaping (Bool) -> Void, updateInAppVibration: @escaping (Bool) -> Void, updateInAppPreviews: @escaping (Bool) -> Void, updateDisplayNameOnLockscreen: @escaping (Bool) -> Void, updateTotalUnreadCountStyle: @escaping (Bool) -> Void, updateTotalUnreadCountCategory: @escaping (Bool) -> Void, resetNotifications: @escaping () -> Void) {
self.account = account
self.presentController = presentController
self.soundSelectionDisposable = soundSelectionDisposable
self.updateMessageAlerts = updateMessageAlerts
self.updateMessagePreviews = updateMessagePreviews
self.updateMessageSound = updateMessageSound
self.updateGroupAlerts = updateGroupAlerts
self.updateGroupPreviews = updateGroupPreviews
self.updateGroupSound = updateGroupSound
self.updateInAppSounds = updateInAppSounds
self.updateInAppVibration = updateInAppVibration
self.updateInAppPreviews = updateInAppPreviews
self.updateDisplayNameOnLockscreen = updateDisplayNameOnLockscreen
self.updateTotalUnreadCountStyle = updateTotalUnreadCountStyle
self.updateTotalUnreadCountCategory = updateTotalUnreadCountCategory
self.resetNotifications = resetNotifications
}
}
private enum NotificationsAndSoundsSection: Int32 {
case messages
case groups
case inApp
case displayNamesOnLockscreen
case badge
case reset
}
private enum NotificationsAndSoundsEntry: ItemListNodeEntry {
case messageHeader(PresentationTheme, String)
case messageAlerts(PresentationTheme, String, Bool)
case messagePreviews(PresentationTheme, String, Bool)
case messageSound(PresentationTheme, String, String, PeerMessageSound)
case messageNotice(PresentationTheme, String)
case groupHeader(PresentationTheme, String)
case groupAlerts(PresentationTheme, String, Bool)
case groupPreviews(PresentationTheme, String, Bool)
case groupSound(PresentationTheme, String, String, PeerMessageSound)
case groupNotice(PresentationTheme, String)
case inAppHeader(PresentationTheme, String)
case inAppSounds(PresentationTheme, String, Bool)
case inAppVibrate(PresentationTheme, String, Bool)
case inAppPreviews(PresentationTheme, String, Bool)
case displayNamesOnLockscreen(PresentationTheme, String, Bool)
case displayNamesOnLockscreenInfo(PresentationTheme, String)
case badgeHeader(PresentationTheme, String)
case unreadCountStyle(PresentationTheme, String, Bool)
case unreadCountCategory(PresentationTheme, String, Bool)
case unreadCountCategoryInfo(PresentationTheme, String)
case reset(PresentationTheme, String)
case resetNotice(PresentationTheme, String)
var section: ItemListSectionId {
switch self {
case .messageHeader, .messageAlerts, .messagePreviews, .messageSound, .messageNotice:
return NotificationsAndSoundsSection.messages.rawValue
case .groupHeader, .groupAlerts, .groupPreviews, .groupSound, .groupNotice:
return NotificationsAndSoundsSection.groups.rawValue
case .inAppHeader, .inAppSounds, .inAppVibrate, .inAppPreviews:
return NotificationsAndSoundsSection.inApp.rawValue
case .displayNamesOnLockscreen, .displayNamesOnLockscreenInfo:
return NotificationsAndSoundsSection.displayNamesOnLockscreen.rawValue
case .badgeHeader, .unreadCountStyle, .unreadCountCategory, .unreadCountCategoryInfo:
return NotificationsAndSoundsSection.badge.rawValue
case .reset, .resetNotice:
return NotificationsAndSoundsSection.reset.rawValue
}
}
var stableId: Int32 {
switch self {
case .messageHeader:
return 0
case .messageAlerts:
return 1
case .messagePreviews:
return 2
case .messageSound:
return 3
case .messageNotice:
return 4
case .groupHeader:
return 5
case .groupAlerts:
return 6
case .groupPreviews:
return 7
case .groupSound:
return 8
case .groupNotice:
return 9
case .inAppHeader:
return 10
case .inAppSounds:
return 11
case .inAppVibrate:
return 12
case .inAppPreviews:
return 13
case .displayNamesOnLockscreen:
return 14
case .displayNamesOnLockscreenInfo:
return 15
case .badgeHeader:
return 16
case .unreadCountStyle:
return 17
case .unreadCountCategory:
return 18
case .unreadCountCategoryInfo:
return 19
case .reset:
return 20
case .resetNotice:
return 21
}
}
static func ==(lhs: NotificationsAndSoundsEntry, rhs: NotificationsAndSoundsEntry) -> Bool {
switch lhs {
case let .messageHeader(lhsTheme, lhsText):
if case let .messageHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .messageAlerts(lhsTheme, lhsText, lhsValue):
if case let .messageAlerts(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .messagePreviews(lhsTheme, lhsText, lhsValue):
if case let .messagePreviews(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .messageSound(lhsTheme, lhsText, lhsValue, lhsSound):
if case let .messageSound(rhsTheme, rhsText, rhsValue, rhsSound) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsSound == rhsSound {
return true
} else {
return false
}
case let .messageNotice(lhsTheme, lhsText):
if case let .messageNotice(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .groupHeader(lhsTheme, lhsText):
if case let .groupHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .groupAlerts(lhsTheme, lhsText, lhsValue):
if case let .groupAlerts(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .groupPreviews(lhsTheme, lhsText, lhsValue):
if case let .groupPreviews(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .groupSound(lhsTheme, lhsText, lhsValue, lhsSound):
if case let .groupSound(rhsTheme, rhsText, rhsValue, rhsSound) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue, lhsSound == rhsSound {
return true
} else {
return false
}
case let .groupNotice(lhsTheme, lhsText):
if case let .groupNotice(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .inAppHeader(lhsTheme, lhsText):
if case let .inAppHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .inAppSounds(lhsTheme, lhsText, lhsValue):
if case let .inAppSounds(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .inAppVibrate(lhsTheme, lhsText, lhsValue):
if case let .inAppVibrate(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .inAppPreviews(lhsTheme, lhsText, lhsValue):
if case let .inAppPreviews(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .displayNamesOnLockscreen(lhsTheme, lhsText, lhsValue):
if case let .displayNamesOnLockscreen(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .displayNamesOnLockscreenInfo(lhsTheme, lhsText):
if case let .displayNamesOnLockscreenInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .badgeHeader(lhsTheme, lhsText):
if case let .badgeHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .unreadCountStyle(lhsTheme, lhsText, lhsValue):
if case let .unreadCountStyle(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .unreadCountCategory(lhsTheme, lhsText, lhsValue):
if case let .unreadCountCategory(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .unreadCountCategoryInfo(lhsTheme, lhsText):
if case let .unreadCountCategoryInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .reset(lhsTheme, lhsText):
if case let .reset(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .resetNotice(lhsTheme, lhsText):
if case let .resetNotice(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
}
}
static func <(lhs: NotificationsAndSoundsEntry, rhs: NotificationsAndSoundsEntry) -> Bool {
return lhs.stableId < rhs.stableId
}
func item(_ arguments: NotificationsAndSoundsArguments) -> ListViewItem {
switch self {
case let .messageHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
case let .messageAlerts(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateMessageAlerts(updatedValue)
})
case let .messagePreviews(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateMessagePreviews(updatedValue)
})
case let .messageSound(theme, text, value, sound):
return ItemListDisclosureItem(theme: theme, title: text, label: value, sectionId: self.section, style: .blocks, action: {
let controller = notificationSoundSelectionController(account: arguments.account, isModal: true, currentSound: sound, defaultSound: nil, completion: { [weak arguments] value in
arguments?.updateMessageSound(value)
})
arguments.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
})
case let .messageNotice(theme, text):
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
case let .groupHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
case let .groupAlerts(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateGroupAlerts(updatedValue)
})
case let .groupPreviews(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateGroupPreviews(updatedValue)
})
case let .groupSound(theme, text, value, sound):
return ItemListDisclosureItem(theme: theme, title: text, label: value, sectionId: self.section, style: .blocks, action: {
let controller = notificationSoundSelectionController(account: arguments.account, isModal: true, currentSound: sound, defaultSound: nil, completion: { [weak arguments] value in
arguments?.updateGroupSound(value)
})
arguments.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
})
case let .groupNotice(theme, text):
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
case let .inAppHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
case let .inAppSounds(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateInAppSounds(updatedValue)
})
case let .inAppVibrate(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateInAppVibration(updatedValue)
})
case let .inAppPreviews(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateInAppPreviews(updatedValue)
})
case let .displayNamesOnLockscreen(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateDisplayNameOnLockscreen(updatedValue)
})
case let .displayNamesOnLockscreenInfo(theme, text):
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
case let .badgeHeader(theme, text):
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
case let .unreadCountStyle(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateTotalUnreadCountStyle(updatedValue)
})
case let .unreadCountCategory(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateTotalUnreadCountCategory(updatedValue)
})
case let .unreadCountCategoryInfo(theme, text):
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
case let .reset(theme, text):
return ItemListActionItem(theme: theme, title: text, kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: {
arguments.resetNotifications()
})
case let .resetNotice(theme, text):
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
}
}
}
private func filteredGlobalSound(_ sound: PeerMessageSound) -> PeerMessageSound {
if case .default = sound {
return .bundledModern(id: 0)
} else {
return sound
}
}
private func notificationsAndSoundsEntries(globalSettings: GlobalNotificationSettingsSet, inAppSettings: InAppNotificationSettings, presentationData: PresentationData) -> [NotificationsAndSoundsEntry] {
var entries: [NotificationsAndSoundsEntry] = []
entries.append(.messageHeader(presentationData.theme, presentationData.strings.Notifications_MessageNotifications))
entries.append(.messageAlerts(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsAlert, globalSettings.privateChats.enabled))
entries.append(.messagePreviews(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsPreview, globalSettings.privateChats.displayPreviews))
entries.append(.messageSound(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsSound, localizedPeerNotificationSoundString(strings: presentationData.strings, sound: filteredGlobalSound(globalSettings.privateChats.sound)), filteredGlobalSound(globalSettings.privateChats.sound)))
entries.append(.messageNotice(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsHelp))
entries.append(.groupHeader(presentationData.theme, presentationData.strings.Notifications_GroupNotifications))
entries.append(.groupAlerts(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsAlert, globalSettings.groupChats.enabled))
entries.append(.groupPreviews(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsPreview, globalSettings.groupChats.displayPreviews))
entries.append(.groupSound(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsSound, localizedPeerNotificationSoundString(strings: presentationData.strings, sound: filteredGlobalSound(globalSettings.groupChats.sound)), filteredGlobalSound(globalSettings.groupChats.sound)))
entries.append(.groupNotice(presentationData.theme, presentationData.strings.Notifications_GroupNotificationsHelp))
entries.append(.inAppHeader(presentationData.theme, presentationData.strings.Notifications_InAppNotifications))
entries.append(.inAppSounds(presentationData.theme, presentationData.strings.Notifications_InAppNotificationsSounds, inAppSettings.playSounds))
entries.append(.inAppVibrate(presentationData.theme, presentationData.strings.Notifications_InAppNotificationsVibrate, inAppSettings.vibrate))
entries.append(.inAppPreviews(presentationData.theme, presentationData.strings.Notifications_InAppNotificationsPreview, inAppSettings.displayPreviews))
entries.append(.displayNamesOnLockscreen(presentationData.theme, presentationData.strings.Notifications_DisplayNamesOnLockScreen, inAppSettings.displayNameOnLockscreen))
entries.append(.displayNamesOnLockscreenInfo(presentationData.theme, presentationData.strings.Notifications_DisplayNamesOnLockScreenInfo))
entries.append(.badgeHeader(presentationData.theme, presentationData.strings.Notifications_Badge))
entries.append(.unreadCountStyle(presentationData.theme, presentationData.strings.Notifications_Badge_IncludeMutedChats, inAppSettings.totalUnreadCountDisplayStyle == .raw))
entries.append(.unreadCountCategory(presentationData.theme, presentationData.strings.Notifications_Badge_CountUnreadMessages, inAppSettings.totalUnreadCountDisplayCategory == .messages))
entries.append(.unreadCountCategoryInfo(presentationData.theme, inAppSettings.totalUnreadCountDisplayCategory == .chats ? presentationData.strings.Notifications_Badge_CountUnreadMessages_InfoOff : presentationData.strings.Notifications_Badge_CountUnreadMessages_InfoOn))
entries.append(.reset(presentationData.theme, presentationData.strings.Notifications_ResetAllNotifications))
entries.append(.resetNotice(presentationData.theme, presentationData.strings.Notifications_ResetAllNotificationsHelp))
return entries
}
public func notificationsAndSoundsController(account: Account) -> ViewController {
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
let arguments = NotificationsAndSoundsArguments(account: account, presentController: { controller, arguments in
presentControllerImpl?(controller, arguments)
}, soundSelectionDisposable: MetaDisposable(), updateMessageAlerts: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedPrivateChats {
return $0.withUpdatedEnabled(value)
}
}).start()
}, updateMessagePreviews: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedPrivateChats {
return $0.withUpdatedDisplayPreviews(value)
}
}).start()
}, updateMessageSound: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedPrivateChats {
return $0.withUpdatedSound(value)
}
}).start()
}, updateGroupAlerts: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedGroupChats {
return $0.withUpdatedEnabled(value)
}
}).start()
}, updateGroupPreviews: { value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedGroupChats {
return $0.withUpdatedDisplayPreviews(value)
}
}).start()
}, updateGroupSound: {value in
let _ = updateGlobalNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedGroupChats {
return $0.withUpdatedSound(value)
}
}).start()
}, updateInAppSounds: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
var settings = settings
settings.playSounds = value
return settings
}).start()
}, updateInAppVibration: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
var settings = settings
settings.vibrate = value
return settings
}).start()
}, updateInAppPreviews: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
var settings = settings
settings.displayPreviews = value
return settings
}).start()
}, updateDisplayNameOnLockscreen: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
var settings = settings
settings.displayNameOnLockscreen = value
return settings
}).start()
}, updateTotalUnreadCountStyle: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
var settings = settings
settings.totalUnreadCountDisplayStyle = value ? .raw : .filtered
return settings
}).start()
}, updateTotalUnreadCountCategory: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
var settings = settings
settings.totalUnreadCountDisplayCategory = value ? .messages : .chats
return settings
}).start()
}, resetNotifications: {
let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Notifications_Reset, color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let modifyPeers = account.postbox.transaction { transaction -> Void in
transaction.resetAllPeerNotificationSettings(TelegramPeerNotificationSettings.defaultSettings)
}
let updateGlobal = updateGlobalNotificationSettingsInteractively(postbox: account.postbox, { _ in
return GlobalNotificationSettingsSet.defaultSettings
})
let reset = resetPeerNotificationSettings(network: account.network)
let signal = combineLatest(modifyPeers, updateGlobal, reset)
let _ = signal.start()
})
]), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
presentControllerImpl?(actionSheet, nil)
})
let preferences = account.postbox.preferencesView(keys: [PreferencesKeys.globalNotifications, ApplicationSpecificPreferencesKeys.inAppNotificationSettings])
let signal = combineLatest((account.applicationContext as! TelegramApplicationContext).presentationData, preferences)
|> map { presentationData, view -> (ItemListControllerState, (ItemListNodeState<NotificationsAndSoundsEntry>, NotificationsAndSoundsEntry.ItemGenerationArguments)) in
let viewSettings: GlobalNotificationSettingsSet
if let settings = view.values[PreferencesKeys.globalNotifications] as? GlobalNotificationSettings {
viewSettings = settings.effective
} else {
viewSettings = GlobalNotificationSettingsSet.defaultSettings
}
let inAppSettings: InAppNotificationSettings
if let settings = view.values[ApplicationSpecificPreferencesKeys.inAppNotificationSettings] as? InAppNotificationSettings {
inAppSettings = settings
} else {
inAppSettings = InAppNotificationSettings.defaultSettings
}
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.Notifications_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
let listState = ItemListNodeState(entries: notificationsAndSoundsEntries(globalSettings: viewSettings, inAppSettings: inAppSettings, presentationData: presentationData), style: .blocks)
return (controllerState, (listState, arguments))
}
let controller = ItemListController(account: account, state: signal)
presentControllerImpl = { [weak controller] c, a in
controller?.present(c, in: .window(.root), with: a)
}
return controller
}