import Foundation import TelegramCore import TelegramPresentationData private let modernSoundsNamePaths: [KeyPath] = [ \.NotificationsSound_Note, \.NotificationsSound_Aurora, \.NotificationsSound_Bamboo, \.NotificationsSound_Chord, \.NotificationsSound_Circles, \.NotificationsSound_Complete, \.NotificationsSound_Hello, \.NotificationsSound_Input, \.NotificationsSound_Keys, \.NotificationsSound_Popcorn, \.NotificationsSound_Pulse, \.NotificationsSound_Synth, \.NotificationsSound_Rebound, \.NotificationsSound_Antic, \.NotificationsSound_Cheers, \.NotificationsSound_Droplet, \.NotificationsSound_Handoff, \.NotificationsSound_Milestone, \.NotificationsSound_Passage, \.NotificationsSound_Portal, \.NotificationsSound_Rattle, \.NotificationsSound_Slide, \.NotificationsSound_Welcome ] private let classicSoundNamePaths: [KeyPath] = [ \.NotificationsSound_Tritone, \.NotificationsSound_Tremolo, \.NotificationsSound_Alert, \.NotificationsSound_Bell, \.NotificationsSound_Calypso, \.NotificationsSound_Chime, \.NotificationsSound_Glass, \.NotificationsSound_Telegraph ] private func soundName(strings: PresentationStrings, sound: PeerMessageSound, notificationSoundList: NotificationSoundList?) -> String { switch sound { case .none: return strings.NotificationsSound_None case .default: return "" case let .bundledModern(id): if id >= 0 && Int(id) < modernSoundsNamePaths.count { return strings[keyPath: modernSoundsNamePaths[Int(id)]] } return "Sound \(id)" case let .bundledClassic(id): if id >= 0 && Int(id) < classicSoundNamePaths.count { return strings[keyPath: classicSoundNamePaths[Int(id)]] } return "Sound \(id)" case let .cloud(fileId): if let (id, legacyCategory) = getCloudLegacySound(id: fileId) { switch legacyCategory { case .modern: if id >= 0 && Int(id) < modernSoundsNamePaths.count { return strings[keyPath: modernSoundsNamePaths[Int(id)]] } case .classic: if id >= 0 && Int(id) < classicSoundNamePaths.count { return strings[keyPath: classicSoundNamePaths[Int(id)]] } } } guard let notificationSoundList = notificationSoundList else { return strings.Channel_NotificationLoading } for sound in notificationSoundList.sounds { if sound.file.fileId.id == fileId { for attribute in sound.file.attributes { switch attribute { case let .Audio(_, _, title, performer, _): if let title = title, !title.isEmpty, let performer = performer, !performer.isEmpty { return "\(title) - \(performer)" } else if let title = title, !title.isEmpty { return title } else if let performer = performer, !performer.isEmpty { return performer } default: break } } if let fileName = sound.file.fileName, !fileName.isEmpty { if let range = fileName.range(of: ".", options: .backwards) { return String(fileName[fileName.startIndex ..< range.lowerBound]) } else { return fileName } } return "Cloud Tone" } } return "" } } public func localizedPeerNotificationSoundString(strings: PresentationStrings, notificationSoundList: NotificationSoundList?, sound: PeerMessageSound, default: PeerMessageSound? = nil) -> String { switch sound { case .default: if let defaultSound = `default` { let name = soundName(strings: strings, sound: defaultSound, notificationSoundList: notificationSoundList) let actualName: String if name.isEmpty { actualName = soundName(strings: strings, sound: defaultCloudPeerNotificationSound, notificationSoundList: notificationSoundList) } else { actualName = name } return strings.UserInfo_NotificationsDefaultSound(actualName).string } else { let name = soundName(strings: strings, sound: defaultCloudPeerNotificationSound, notificationSoundList: notificationSoundList) return name } default: let name = soundName(strings: strings, sound: sound, notificationSoundList: notificationSoundList) if name.isEmpty { return localizedPeerNotificationSoundString(strings: strings, notificationSoundList: notificationSoundList, sound: .default, default: `default`) } else { return name } } }