mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-02-22 10:33:18 +00:00
4670 lines
194 KiB
Swift
4670 lines
194 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import Display
|
|
import SwiftSignalKit
|
|
import Postbox
|
|
import TelegramCore
|
|
import TelegramUIPreferences
|
|
import TelegramCallsUI
|
|
import OverlayStatusController
|
|
import AccountContext
|
|
import PassportUI
|
|
import LocalAuth
|
|
import CallListUI
|
|
import ChatListUI
|
|
import NotificationSoundSelectionUI
|
|
import PresentationDataUtils
|
|
import PhoneNumberFormat
|
|
import AccountUtils
|
|
import InstantPageCache
|
|
import NotificationPeerExceptionController
|
|
import QrCodeUI
|
|
import PremiumUI
|
|
import StorageUsageScreen
|
|
import PeerInfoStoryGridScreen
|
|
import WallpaperGridScreen
|
|
import PeerNameColorScreen
|
|
import UndoUI
|
|
import PasskeysScreen
|
|
import ContextUI
|
|
import QuickReactionSetupController
|
|
import AvatarEditorScreen
|
|
import PeerSelectionScreen
|
|
import DeviceModel
|
|
|
|
enum SettingsSearchableItemIcon {
|
|
case profile
|
|
case proxy
|
|
case savedMessages
|
|
case calls
|
|
case stickers
|
|
case notifications
|
|
case privacy
|
|
case data
|
|
case appearance
|
|
case language
|
|
case watch
|
|
case passport
|
|
case support
|
|
case faq
|
|
case tips
|
|
case chatFolders
|
|
case deleteAccount
|
|
case devices
|
|
case premium
|
|
case business
|
|
case stars
|
|
case ton
|
|
case stories
|
|
case myProfile
|
|
case gift
|
|
case powerSaving
|
|
}
|
|
|
|
public enum SettingsSearchableItemPresentation {
|
|
case push
|
|
case modal
|
|
case immediate
|
|
case dismiss
|
|
}
|
|
|
|
public struct SettingsSearchableItem {
|
|
public let id: AnyHashable
|
|
let title: String
|
|
let alternate: [String]
|
|
let icon: SettingsSearchableItemIcon
|
|
let breadcrumbs: [String]
|
|
let isVisible: Bool
|
|
public let present: (AccountContext, NavigationController?, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void
|
|
|
|
init(
|
|
id: AnyHashable,
|
|
title: String = "",
|
|
alternate: [String] = [],
|
|
icon: SettingsSearchableItemIcon = .privacy,
|
|
breadcrumbs: [String] = [],
|
|
isVisible: Bool = true,
|
|
present: @escaping (AccountContext, NavigationController?, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void
|
|
) {
|
|
self.id = id
|
|
self.title = title
|
|
self.alternate = alternate
|
|
self.icon = icon
|
|
self.breadcrumbs = breadcrumbs
|
|
self.isVisible = isVisible
|
|
self.present = present
|
|
}
|
|
|
|
func withUpdatedTitle(_ title: String) -> SettingsSearchableItem {
|
|
return SettingsSearchableItem(id: self.id, title: title, alternate: self.alternate, icon: self.icon, breadcrumbs: self.breadcrumbs, isVisible: self.isVisible, present: self.present)
|
|
}
|
|
}
|
|
|
|
private func synonyms(_ string: String?) -> [String] {
|
|
if let string = string, !string.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
|
|
return string.components(separatedBy: "\n")
|
|
} else {
|
|
return []
|
|
}
|
|
}
|
|
|
|
private func profileSearchableItems(
|
|
context: AccountContext,
|
|
canAddAccount: Bool
|
|
) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .profile
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "search",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
|
rootController.openSettings(edit: false)
|
|
Queue.mainQueue().after(0.1) {
|
|
rootController.getSettingsController()?.tabBarActivateSearch()
|
|
}
|
|
}
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
|
rootController.openSettings(edit: true)
|
|
}
|
|
}
|
|
)
|
|
)
|
|
//TODO:highlight
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/first-name",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
|
rootController.openSettings(edit: true)
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
//TODO:highlight
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/last-name",
|
|
icon: .profile,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
|
rootController.openSettings(edit: true)
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
//TODO:highlight
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/bio",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
|
rootController.openSettings(edit: true)
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/change-number",
|
|
title: strings.Settings_PhoneNumber,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_EditProfile_PhoneNumber),
|
|
icon: icon,
|
|
breadcrumbs: [strings.EditProfile_Title],
|
|
present: { context, _, present in
|
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
|
|> deliverOnMainQueue).start(next: { peer in
|
|
var phoneNumber: String?
|
|
if case let .user(user) = peer {
|
|
phoneNumber = user.phone
|
|
}
|
|
present(.push, PrivacyIntroController(context: context, mode: .changePhoneNumber(phoneNumber ?? ""), proceedAction: {
|
|
present(.push, ChangePhoneNumberController(context: context))
|
|
}))
|
|
})
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/username",
|
|
title: strings.Settings_Username,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_EditProfile_Username),
|
|
icon: icon,
|
|
breadcrumbs: [strings.EditProfile_Title],
|
|
present: { context, _, present in
|
|
let controller = usernameSetupController(context: context)
|
|
present(.modal, controller)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/your-color",
|
|
title: strings.Settings_YourColor,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.EditProfile_Title],
|
|
present: { context, _, present in
|
|
let controller = UserAppearanceScreen(context: context)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/channel",
|
|
title: strings.Settings_PersonalChannelItem,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.EditProfile_Title],
|
|
present: { context, _, present in
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
let _ = (context.engine.peers.adminedPublicChannels(scope: .forPersonalProfile)
|
|
|> deliverOnMainQueue).start(next: { personalChannels in
|
|
let _ = (PeerSelectionScreen.initialData(context: context, channels: personalChannels)
|
|
|> deliverOnMainQueue).start(next: { initialData in
|
|
present(.push, PeerSelectionScreen(context: context, initialData: initialData, updatedPresentationData: nil, completion: { channel in
|
|
if initialData.channelId == channel?.peer.id {
|
|
return
|
|
}
|
|
|
|
let toastText: String
|
|
var mappedChannel: TelegramPersonalChannel?
|
|
if let channel {
|
|
mappedChannel = TelegramPersonalChannel(peerId: channel.peer.id, subscriberCount: channel.subscriberCount.flatMap(Int32.init(clamping:)), topMessageId: nil)
|
|
if initialData.channelId != nil {
|
|
toastText = presentationData.strings.Settings_PersonalChannelUpdatedToast
|
|
} else {
|
|
toastText = presentationData.strings.Settings_PersonalChannelAddedToast
|
|
}
|
|
} else {
|
|
toastText = presentationData.strings.Settings_PersonalChannelRemovedToast
|
|
}
|
|
let _ = context.engine.accountData.updatePersonalChannel(personalChannel: mappedChannel).startStandalone()
|
|
|
|
present(.immediate, UndoOverlayController(presentationData: presentationData, content: .actionSucceeded(title: nil, text: toastText, cancel: nil, destructive: false), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }))
|
|
}))
|
|
})
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/birthday",
|
|
title: strings.Settings_Birthday,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.EditProfile_Title],
|
|
present: { context, _, present in
|
|
presentSetupBirthday(context: context, present: present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "emoji-status",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
|
rootController.openSettings(edit: false)
|
|
Queue.mainQueue().justDispatch {
|
|
if let settingsScreen = rootController.getSettingsController() as? PeerInfoScreen {
|
|
settingsScreen.openEmojiStatusSetup()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "profile-photo",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
|
rootController.openPhotoSetup(completedWithUploadingImage: { [weak rootController] _, _ in
|
|
rootController?.openSettings(edit: false)
|
|
return nil
|
|
})
|
|
}
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "profile-photo/use-emoji",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let controller = AvatarEditorScreen(context: context, inputData: AvatarEditorScreen.inputData(context: context, isGroup: false), peerType: .user, markup: nil)
|
|
controller.imageCompletion = { image, commit in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface, let settingsController = rootController.getSettingsController() as? PeerInfoScreen {
|
|
settingsController.updateProfilePhoto(image)
|
|
commit()
|
|
}
|
|
}
|
|
controller.videoCompletion = { image, url, values, markup, commit in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface, let settingsController = rootController.getSettingsController() as? PeerInfoScreen {
|
|
settingsController.updateProfileVideo(image, video: nil, values: nil, markup: markup)
|
|
commit()
|
|
}
|
|
}
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
|
|
if canAddAccount {
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/add-account",
|
|
title: strings.Settings_AddAccount,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_EditProfile_AddAccount),
|
|
icon: icon,
|
|
breadcrumbs: [strings.EditProfile_Title],
|
|
present: { context, _, present in
|
|
let isTestingEnvironment = context.account.testingEnvironment
|
|
context.sharedContext.beginNewAuth(testingEnvironment: isTestingEnvironment)
|
|
}
|
|
)
|
|
)
|
|
}
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "edit/log-out",
|
|
title: strings.Settings_Logout,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_EditProfile_Logout),
|
|
icon: icon,
|
|
breadcrumbs: [strings.EditProfile_Title],
|
|
present: { context, navigationController, present in
|
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
|
|> deliverOnMainQueue).start(next: { peer in
|
|
var phoneNumber: String?
|
|
if case let .user(user) = peer {
|
|
phoneNumber = user.phone
|
|
}
|
|
if let navigationController {
|
|
present(.modal, logoutOptionsController(context: context, navigationController: navigationController, canAddAccounts: canAddAccount, phoneNumber: phoneNumber ?? ""))
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "profile-color",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let controller = UserAppearanceScreen(context: context)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "profile-color/profile",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let controller = UserAppearanceScreen(context: context)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "profile-color/profile/add-icons",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let controller = UserAppearanceScreen(context: context, focusOnItemTag: .profileAddIcons)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "profile-color/profile/use-gift",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let controller = UserAppearanceScreen(context: context, focusOnItemTag: .profileUseGift)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "profile-color/name",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let controller = UserAppearanceScreen(context: context, focusOnItemTag: .name)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "profile-color/name/add-icons",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let controller = UserAppearanceScreen(context: context, focusOnItemTag: .nameAddIcons)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "profile-color/name/use-gift",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let controller = UserAppearanceScreen(context: context, focusOnItemTag: .nameUseGift)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
|
|
return items
|
|
}
|
|
|
|
private func devicesSearchableItems(context: AccountContext, activeSessionsContext: ActiveSessionsContext?, webSessionsContext: WebSessionsContext?) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .devices
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
if let activeSessionsContext = activeSessionsContext {
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "devices",
|
|
title: strings.Settings_Devices,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_AuthSessions) + [strings.PrivacySettings_AuthSessions],
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext, webSessionsContext: webSessionsContext ?? context.engine.privacy.webSessions(), websitesOnly: false))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "devices/edit",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext, webSessionsContext: webSessionsContext ?? context.engine.privacy.webSessions(), websitesOnly: false, focusOnItemTag: .edit))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "devices/terminate-sessions",
|
|
title: strings.AuthSessions_TerminateOtherSessions,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Devices_TerminateOtherSessions),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Devices],
|
|
present: { context, _, present in
|
|
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext, webSessionsContext: webSessionsContext ?? context.engine.privacy.webSessions(), websitesOnly: false, focusOnItemTag: .terminateOtherSessions))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "devices/link-desktop",
|
|
title: strings.AuthSessions_LinkDesktopDevice,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Devices_LinkDesktopDevice),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Devices],
|
|
present: { context, _, present in
|
|
present(.push, QrCodeScanScreen(context: context, subject: .authTransfer(activeSessionsContext: activeSessionsContext)))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "devices/auto-terminate",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext, webSessionsContext: webSessionsContext ?? context.engine.privacy.webSessions(), websitesOnly: false, focusOnItemTag: .autoTerminate))
|
|
}
|
|
)
|
|
)
|
|
}
|
|
return items
|
|
}
|
|
|
|
private func premiumSearchableItems(context: AccountContext) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .premium
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium",
|
|
title: strings.Settings_Premium,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
present(.push, PremiumIntroScreen(context: context, source: .settings, modal: false))
|
|
}
|
|
)
|
|
)
|
|
|
|
let presentDemo: (PremiumDemoScreen.Subject, (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { subject, present in
|
|
var replaceImpl: ((ViewController) -> Void)?
|
|
let controller = PremiumDemoScreen(context: context, subject: subject, action: {
|
|
let controller = PremiumIntroScreen(context: context, source: .settings, modal: false)
|
|
replaceImpl?(controller)
|
|
})
|
|
replaceImpl = { [weak controller] c in
|
|
controller?.replace(with: c)
|
|
}
|
|
present(.push, controller)
|
|
}
|
|
|
|
let openResolvedUrl: (ResolvedUrl, NavigationController?, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { resolvedUrl, navigationController, present in
|
|
context.sharedContext.openResolvedUrl(
|
|
resolvedUrl,
|
|
context: context,
|
|
urlContext: .generic,
|
|
navigationController: navigationController,
|
|
forceExternal: false,
|
|
forceUpdate: false,
|
|
openPeer: { peer, navigation in },
|
|
sendFile: nil,
|
|
sendSticker: nil,
|
|
sendEmoji: nil,
|
|
requestMessageActionUrlAuth: nil,
|
|
joinVoiceChat: nil,
|
|
present: { controller, arguments in
|
|
present(.push, controller)
|
|
},
|
|
dismissInput: {},
|
|
contentContext: nil,
|
|
progress: nil,
|
|
completion: nil
|
|
)
|
|
}
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/doubled-limits",
|
|
title: strings.Premium_DoubledLimits,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_DoubledLimits),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { _, _, present in
|
|
presentDemo(.doubleLimits, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/unlimited-cloud-storage",
|
|
title: strings.Premium_UploadSize,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_UploadSize),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.moreUpload, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/faster-download-speed",
|
|
title: strings.Premium_FasterSpeed,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_FasterSpeed),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.fasterDownload, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/voice-to-text",
|
|
title: strings.Premium_VoiceToText,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_VoiceToText),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.voiceToText, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/no-ads",
|
|
title: strings.Premium_NoAds,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_NoAds),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.noAds, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/emoji-statuses",
|
|
title: strings.Premium_EmojiStatus,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_EmojiStatus),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.emojiStatus, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/unique-reactions",
|
|
title: strings.Premium_Reactions,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_Reactions),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.uniqueReactions, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/premium-stickers",
|
|
title: strings.Premium_Stickers,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_Stickers),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.premiumStickers, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/animated-emoji",
|
|
title: strings.Premium_AnimatedEmoji,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_AnimatedEmoji),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.animatedEmoji, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/advanced-chat-management",
|
|
title: strings.Premium_ChatManagement,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_ChatManagement),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.advancedChatManagement, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/profile-badge",
|
|
title: strings.Premium_Badge,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_Badge),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.profileBadge, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/animated-profile-pictures",
|
|
title: strings.Premium_Avatar,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_Avatar),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.animatedUserpics, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "premium/app-icons",
|
|
title: strings.Premium_AppIcon,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Premium_AppIcon),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Premium],
|
|
present: { context, _, present in
|
|
presentDemo(.appIcons, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "business",
|
|
title: strings.Settings_Business,
|
|
alternate: [],
|
|
icon: .business,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
present(.push, PremiumIntroScreen(context: context, mode: .business, source: .settings, modal: false))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "business/do-not-hide-ads",
|
|
title: strings.Business_DontHideAds,
|
|
alternate: [],
|
|
icon: .business,
|
|
breadcrumbs: [strings.Settings_Business],
|
|
present: { context, _, present in
|
|
present(.push, PremiumIntroScreen(context: context, mode: .business, source: .settings, modal: false, focusOnItemTag: .doNotHideAds))
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "stars",
|
|
title: strings.Settings_Stars,
|
|
alternate: [],
|
|
icon: .stars,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
guard let starsContext = context.starsContext else {
|
|
return
|
|
}
|
|
let controller = context.sharedContext.makeStarsTransactionsScreen(context: context, starsContext: starsContext)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "stars/top-up",
|
|
icon: .stars,
|
|
isVisible: false,
|
|
present: { context, navigationController, present in
|
|
openResolvedUrl(.starsTopup(amount: nil, purpose: nil), navigationController, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "stars/stats",
|
|
icon: .stars,
|
|
isVisible: false,
|
|
present: { context, navigationController, present in
|
|
let starsRevenueStatsContext = StarsRevenueStatsContext(account: context.account, peerId: context.account.peerId, ton: false)
|
|
let controller = context.sharedContext.makeStarsStatisticsScreen(context: context, peerId: context.account.peerId, revenueContext: starsRevenueStatsContext)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "stars/gift",
|
|
icon: .stars,
|
|
isVisible: false,
|
|
present: { context, navigationController, present in
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
|
|
let _ = combineLatest(queue: Queue.mainQueue(),
|
|
context.engine.payments.starsTopUpOptions(),
|
|
context.account.stateManager.contactBirthdays |> take(1)
|
|
).start(next: { [weak navigationController] options, birthdays in
|
|
guard let starsContext = context.starsContext else {
|
|
return
|
|
}
|
|
let controller = context.sharedContext.makeStarsGiftController(context: context, birthdays: birthdays, completion: { [weak navigationController] peerIds in
|
|
guard let peerId = peerIds.first else {
|
|
return
|
|
}
|
|
let purchaseController = context.sharedContext.makeStarsPurchaseScreen(
|
|
context: context,
|
|
starsContext: starsContext,
|
|
options: options,
|
|
purpose: .gift(peerId: peerId),
|
|
targetPeerId: nil,
|
|
customTheme: nil,
|
|
completion: { [weak navigationController] stars in
|
|
if let navigationController {
|
|
var controllers = navigationController.viewControllers
|
|
controllers = controllers.filter { !($0 is ContactSelectionController) }
|
|
navigationController.setViewControllers(controllers, animated: true)
|
|
}
|
|
|
|
Queue.mainQueue().after(2.0) {
|
|
let resultController = UndoOverlayController(
|
|
presentationData: presentationData,
|
|
content: .universal(
|
|
animation: "StarsSend",
|
|
scale: 0.066,
|
|
colors: [:],
|
|
title: nil,
|
|
text: presentationData.strings.Stars_Intro_StarsSent(Int32(stars)),
|
|
customUndoText: presentationData.strings.Stars_Intro_StarsSent_ViewChat,
|
|
timeout: nil
|
|
),
|
|
elevatedLayout: false,
|
|
action: { [weak navigationController] action in
|
|
if case .undo = action, let navigationController {
|
|
let _ = (context.engine.data.get(
|
|
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
|
)
|
|
|> deliverOnMainQueue).start(next: { peer in
|
|
guard let peer else {
|
|
return
|
|
}
|
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, chatController: nil, context: context, chatLocation: .peer(peer), subject: nil, botStart: nil, updateTextInputState: nil, keepStack: .always, useExisting: true, purposefulAction: nil, scrollToEndIfExists: false, activateMessageSearch: nil, animated: true))
|
|
})
|
|
}
|
|
return true
|
|
}
|
|
)
|
|
present(.immediate, resultController)
|
|
}
|
|
}
|
|
)
|
|
present(.push, purchaseController)
|
|
})
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
var canJoinRefProgram = false
|
|
if let data = context.currentAppConfiguration.with({ $0 }).data, let value = data["starref_connect_allowed"] {
|
|
if let value = value as? Double {
|
|
canJoinRefProgram = value != 0.0
|
|
} else if let value = value as? Bool {
|
|
canJoinRefProgram = value
|
|
}
|
|
}
|
|
if canJoinRefProgram {
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "stars/earn",
|
|
title: strings.Monetization_EarnStarsInfo_Title,
|
|
alternate: [],
|
|
icon: .stars,
|
|
breadcrumbs: [strings.Settings_Stars],
|
|
present: { context, navigationController, present in
|
|
let _ = (context.sharedContext.makeAffiliateProgramSetupScreenInitialData(context: context, peerId: context.account.peerId, mode: .connectedPrograms)
|
|
|> deliverOnMainQueue).startStandalone(next: { initialData in
|
|
let controller = context.sharedContext.makeAffiliateProgramSetupScreen(context: context, initialData: initialData)
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
)
|
|
)
|
|
}
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "ton",
|
|
title: strings.Settings_MyTon,
|
|
alternate: [],
|
|
icon: .ton,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
guard let tonContext = context.tonContext else {
|
|
return
|
|
}
|
|
let controller = context.sharedContext.makeStarsTransactionsScreen(context: context, starsContext: tonContext)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "send-gift",
|
|
title: strings.Settings_SendGift,
|
|
alternate: [],
|
|
icon: .gift,
|
|
breadcrumbs: [],
|
|
present: { context, navigationController, present in
|
|
openResolvedUrl(.sendGift(peerId: nil), navigationController, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "send-gift/self",
|
|
title: strings.Settings_SendGift,
|
|
alternate: [],
|
|
icon: .gift,
|
|
breadcrumbs: [],
|
|
isVisible: false,
|
|
present: { context, navigationController, present in
|
|
openResolvedUrl(.sendGift(peerId: context.account.peerId), navigationController, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
return items
|
|
}
|
|
|
|
private func myProfileSearchableItems(context: AccountContext) -> [SettingsSearchableItem] {
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "qr-code",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
|
|> deliverOnMainQueue).start(next: { peer in
|
|
guard let peer = peer?._asPeer() else {
|
|
return
|
|
}
|
|
let controller = context.sharedContext.makeChatQrCodeScreen(context: context, peer: peer, threadId: nil, temporary: false)
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
//TODO:fix
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "qr-code/share",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
|
|> deliverOnMainQueue).start(next: { peer in
|
|
guard let peer = peer?._asPeer() else {
|
|
return
|
|
}
|
|
let controller = context.sharedContext.makeChatQrCodeScreen(context: context, peer: peer, threadId: nil, temporary: false)
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "qr-code/scan",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let scanController = QrCodeScanScreen(context: context, subject: .peer)
|
|
present(.push, scanController)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "my-profile",
|
|
title: strings.Settings_MyProfile,
|
|
alternate: [],
|
|
icon: .myProfile,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
|
|> deliverOnMainQueue).start(next: { peer in
|
|
guard let peer = peer?._asPeer() else {
|
|
return
|
|
}
|
|
let controller = context.sharedContext.makePeerInfoController(
|
|
context: context,
|
|
updatedPresentationData: nil,
|
|
peer: peer,
|
|
mode: .myProfile,
|
|
avatarInitiallyExpanded: false,
|
|
fromChat: false,
|
|
requestsContext: nil
|
|
)
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "my-profile/edit",
|
|
icon: .myProfile,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
|
|> deliverOnMainQueue).start(next: { peer in
|
|
guard let peer = peer?._asPeer() else {
|
|
return
|
|
}
|
|
let controller = context.sharedContext.makePeerInfoController(
|
|
context: context,
|
|
updatedPresentationData: nil,
|
|
peer: peer,
|
|
mode: .myProfile,
|
|
avatarInitiallyExpanded: false,
|
|
fromChat: false,
|
|
requestsContext: nil
|
|
)
|
|
present(.push, controller)
|
|
|
|
Queue.mainQueue().justDispatch {
|
|
if let controller = controller as? PeerInfoScreen {
|
|
controller.activateEdit()
|
|
}
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "my-profile/gifts",
|
|
title: strings.Gift_Options_Gift_Filter_MyGifts,
|
|
alternate: [],
|
|
icon: .myProfile,
|
|
breadcrumbs: [strings.Settings_MyProfile],
|
|
present: { context, _, present in
|
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
|
|> deliverOnMainQueue).start(next: { peer in
|
|
guard let peer = peer?._asPeer() else {
|
|
return
|
|
}
|
|
let controller = context.sharedContext.makePeerInfoController(
|
|
context: context,
|
|
updatedPresentationData: nil,
|
|
peer: peer,
|
|
mode: .myProfileGifts,
|
|
avatarInitiallyExpanded: false,
|
|
fromChat: false,
|
|
requestsContext: nil
|
|
)
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "my-profile/posts",
|
|
title: strings.Settings_MyStories,
|
|
alternate: [],
|
|
icon: .stories,
|
|
breadcrumbs: [strings.Settings_MyProfile],
|
|
present: { context, _, present in
|
|
present(.push, PeerInfoStoryGridScreen(context: context, peerId: context.account.peerId, scope: .saved))
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "my-profile/posts/all-stories",
|
|
icon: .stories,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, PeerInfoStoryGridScreen(context: context, peerId: context.account.peerId, scope: .saved))
|
|
}
|
|
)
|
|
)
|
|
|
|
//TODO:fix
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "my-profile/posts/add-album",
|
|
icon: .stories,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, PeerInfoStoryGridScreen(context: context, peerId: context.account.peerId, scope: .saved))
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "my-profile/archived-posts",
|
|
title: strings.Settings_StoriesArchive,
|
|
alternate: [],
|
|
icon: .stories,
|
|
breadcrumbs: [strings.Settings_MyProfile],
|
|
present: { context, _, present in
|
|
present(.push, PeerInfoStoryGridScreen(context: context, peerId: context.account.peerId, scope: .archive))
|
|
}
|
|
)
|
|
)
|
|
|
|
return items
|
|
}
|
|
|
|
|
|
private func callSearchableItems(context: AccountContext) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .calls
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let presentCallSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, CallListEntryTag?) -> Void = { context, present, itemTag in
|
|
present(.push, CallListController(context: context, mode: .navigation, focusOnItemTag: itemTag))
|
|
}
|
|
return [
|
|
SettingsSearchableItem(
|
|
id: "calls",
|
|
title: strings.CallSettings_RecentCalls,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Calls_Title),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
presentCallSettings(context, present, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "calls/all",
|
|
title: strings.Calls_All,
|
|
icon: icon,
|
|
breadcrumbs: [strings.CallSettings_RecentCalls],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentCallSettings(context, present, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "calls/missed",
|
|
title: strings.Calls_Missed,
|
|
icon: icon,
|
|
breadcrumbs: [strings.CallSettings_RecentCalls],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentCallSettings(context, present, .missed)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "calls/edit",
|
|
icon: icon,
|
|
breadcrumbs: [strings.CallSettings_RecentCalls],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentCallSettings(context, present, .edit)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "calls/show-tab",
|
|
title: strings.CallSettings_TabIcon,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Calls_CallTab),
|
|
icon: icon,
|
|
breadcrumbs: [strings.CallSettings_RecentCalls],
|
|
present: { context, _, present in
|
|
presentCallSettings(context, present, .showTab)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "calls/start-call",
|
|
title: strings.Calls_StartNewCall,
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface {
|
|
rootController.startNewCall()
|
|
}
|
|
}
|
|
)
|
|
]
|
|
}
|
|
|
|
private func chatFoldersSearchableItems(context: AccountContext) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .chatFolders
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let presentChatFoldersSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, ChatListFilterPresetListEntryTag?) -> Void = { context, present, itemTag in
|
|
present(.push, chatListFilterPresetListController(context: context, mode: .default, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "folders",
|
|
title: strings.Settings_ChatFolders,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_ChatFolders),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
presentChatFoldersSettings(context, present, nil)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "folders/edit",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatFolders],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentChatFoldersSettings(context, present, .edit)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "folders/create",
|
|
title: strings.ChatListFolderSettings_NewFolder,
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatFolders],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let filtersWithCounts = context.engine.peers.updatedChatListFilters()
|
|
|> distinctUntilChanged
|
|
|> mapToSignal { filters -> Signal<[(ChatListFilter, Int)], NoError> in
|
|
return .single(filters.map { filter -> (ChatListFilter, Int) in
|
|
return (filter, 0)
|
|
})
|
|
}
|
|
|
|
let _ = combineLatest(
|
|
queue: Queue.mainQueue(),
|
|
context.engine.data.get(
|
|
TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId),
|
|
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: false),
|
|
TelegramEngine.EngineData.Item.Configuration.UserLimits(isPremium: true)
|
|
),
|
|
filtersWithCounts |> take(1)
|
|
).start(next: { result, filters in
|
|
let (accountPeer, limits, premiumLimits) = result
|
|
let isPremium = accountPeer?.isPremium ?? false
|
|
|
|
let filters = filters.filter { filter in
|
|
if case .allChats = filter.0 {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
let limit = limits.maxFoldersCount
|
|
let premiumLimit = premiumLimits.maxFoldersCount
|
|
if filters.count >= premiumLimit {
|
|
let controller = PremiumLimitScreen(context: context, subject: .folders, count: Int32(filters.count), action: {
|
|
return true
|
|
})
|
|
present(.push, controller)
|
|
return
|
|
} else if filters.count >= limit && !isPremium {
|
|
var replaceImpl: ((ViewController) -> Void)?
|
|
let controller = PremiumLimitScreen(context: context, subject: .folders, count: Int32(filters.count), action: {
|
|
let controller = PremiumIntroScreen(context: context, source: .folders)
|
|
replaceImpl?(controller)
|
|
return true
|
|
})
|
|
replaceImpl = { [weak controller] c in
|
|
controller?.replace(with: c)
|
|
}
|
|
present(.push, controller)
|
|
return
|
|
}
|
|
present(.push, chatListFilterPresetController(context: context, currentPreset: nil, updated: { _ in }))
|
|
})
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "folders/add-recommended",
|
|
title: strings.ChatListFolderSettings_RecommendedFoldersSection.capitalized,
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatFolders],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentChatFoldersSettings(context, present, .addRecommended)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "folders/show-tags",
|
|
title: strings.ChatListFilterList_ShowTags,
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatFolders],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentChatFoldersSettings(context, present, .displayTags)
|
|
}
|
|
)
|
|
)
|
|
|
|
return items
|
|
}
|
|
|
|
private func stickerSearchableItems(context: AccountContext, archivedStickerPacks: [ArchivedStickerPackItem]?) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .stickers
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let presentStickerSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, InstalledStickerPacksControllerMode, InstalledStickerPacksEntryTag?) -> Void = { context, present, mode, itemTag in
|
|
present(.push, installedStickerPacksController(context: context, mode: mode, archivedPacks: archivedStickerPacks, updatedPacks: { _ in }, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji",
|
|
title: strings.ChatSettings_Stickers,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_Title),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
presentStickerSettings(context, present, .general, nil)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/edit",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentStickerSettings(context, present, .general, .edit)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/suggest-by-emoji",
|
|
title: strings.Stickers_SuggestStickers,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_SuggestStickers),
|
|
icon: icon,
|
|
breadcrumbs: [strings.ChatSettings_Stickers],
|
|
present: { context, _, present in
|
|
presentStickerSettings(context, present, .general, .suggestOptions)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/trending",
|
|
title: strings.StickerPacksSettings_FeaturedPacks,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_FeaturedPacks),
|
|
icon: icon,
|
|
breadcrumbs: [strings.ChatSettings_Stickers],
|
|
present: { context, _, present in
|
|
present(.push, featuredStickerPacksController(context: context))
|
|
}
|
|
)
|
|
)
|
|
if !(archivedStickerPacks?.isEmpty ?? true) {
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/archived",
|
|
title: strings.StickerPacksSettings_ArchivedPacks,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Stickers_ArchivedPacks),
|
|
icon: icon,
|
|
breadcrumbs: [strings.ChatSettings_Stickers],
|
|
present: { context, _, present in
|
|
present(.push, archivedStickerPacksController(context: context, mode: .stickers, archived: archivedStickerPacks, updatedPacks: { _ in }))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/archived/edit",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, archivedStickerPacksController(context: context, mode: .stickers, archived: archivedStickerPacks, updatedPacks: { _ in }, forceEdit: true))
|
|
}
|
|
)
|
|
)
|
|
}
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/large",
|
|
title: strings.Appearance_LargeEmoji,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_LargeEmoji),
|
|
icon: icon,
|
|
breadcrumbs: [strings.ChatSettings_Stickers],
|
|
present: { context, _, present in
|
|
presentStickerSettings(context, present, .general, .largeEmoji)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/dynamic-order",
|
|
title: strings.StickerPacksSettings_DynamicOrder,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.ChatSettings_Stickers],
|
|
present: { context, _, present in
|
|
presentStickerSettings(context, present, .general, .dynamicOrder)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/emoji",
|
|
title: strings.StickerPacksSettings_Emoji,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.ChatSettings_Stickers],
|
|
present: { context, _, present in
|
|
presentStickerSettings(context, present, .emoji, nil)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/emoji/edit",
|
|
icon: icon,
|
|
breadcrumbs: [strings.StickerPacksSettings_Emoji],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentStickerSettings(context, present, .emoji, .edit)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/emoji/suggest",
|
|
icon: icon,
|
|
breadcrumbs: [strings.StickerPacksSettings_Emoji],
|
|
present: { context, _, present in
|
|
presentStickerSettings(context, present, .emoji, .suggestOptions)
|
|
}
|
|
)
|
|
)
|
|
if !(archivedStickerPacks?.isEmpty ?? true) {
|
|
//TODO:fix
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/emoji/archived",
|
|
title: strings.StickerPacksSettings_ArchivedPacks,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.ChatSettings_Stickers],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, archivedStickerPacksController(context: context, mode: .emoji, archived: archivedStickerPacks, updatedPacks: { _ in }))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/emoji/archived/edit",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, archivedStickerPacksController(context: context, mode: .emoji, archived: archivedStickerPacks, updatedPacks: { _ in }, forceEdit: true))
|
|
}
|
|
)
|
|
)
|
|
}
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/emoji/quick-reaction",
|
|
title: strings.Settings_QuickReactionSetup_Title,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.ChatSettings_Stickers],
|
|
present: { context, _, present in
|
|
present(.push, quickReactionSetupController(context: context))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/stickers-and-emoji/emoji/quick-reaction/choose",
|
|
icon: icon,
|
|
breadcrumbs: [strings.ChatSettings_Stickers, strings.Settings_QuickReactionSetup_Title],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, quickReactionSetupController(context: context, focusOnItemTag: .choose))
|
|
}
|
|
)
|
|
)
|
|
|
|
return items
|
|
}
|
|
|
|
private func notificationSearchableItems(context: AccountContext, settings: GlobalNotificationSettingsSet, exceptionsList: NotificationExceptionsList?) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .notifications
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let presentNotificationSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, NotificationsAndSoundsEntryTag?) -> Void = { context, present, itemTag in
|
|
present(.push, notificationsAndSoundsController(context: context, exceptionsList: exceptionsList, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
let defaultStorySettings = PeerStoryNotificationSettings.default
|
|
let exceptions = { () -> (NotificationExceptionMode, NotificationExceptionMode, NotificationExceptionMode, NotificationExceptionMode) in
|
|
var users:[PeerId : NotificationExceptionWrapper] = [:]
|
|
var groups: [PeerId : NotificationExceptionWrapper] = [:]
|
|
var channels: [PeerId : NotificationExceptionWrapper] = [:]
|
|
var stories: [PeerId : NotificationExceptionWrapper] = [:]
|
|
|
|
if let list = exceptionsList {
|
|
for (key, value) in list.settings {
|
|
if let peer = list.peers[key], !peer.debugDisplayTitle.isEmpty, peer.id != context.account.peerId {
|
|
if value.storySettings != defaultStorySettings {
|
|
stories[key] = NotificationExceptionWrapper(settings: value, peer: EnginePeer(peer))
|
|
}
|
|
|
|
switch value.muteState {
|
|
case .default:
|
|
switch value.messageSound {
|
|
case .default:
|
|
break
|
|
default:
|
|
switch key.namespace {
|
|
case Namespaces.Peer.CloudUser:
|
|
users[key] = NotificationExceptionWrapper(settings: value, peer: EnginePeer(peer))
|
|
default:
|
|
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
|
|
channels[key] = NotificationExceptionWrapper(settings: value, peer: .channel(peer))
|
|
} else {
|
|
groups[key] = NotificationExceptionWrapper(settings: value, peer: EnginePeer(peer))
|
|
}
|
|
}
|
|
}
|
|
default:
|
|
switch key.namespace {
|
|
case Namespaces.Peer.CloudUser:
|
|
users[key] = NotificationExceptionWrapper(settings: value, peer: EnginePeer(peer))
|
|
default:
|
|
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
|
|
channels[key] = NotificationExceptionWrapper(settings: value, peer: .channel(peer))
|
|
} else {
|
|
groups[key] = NotificationExceptionWrapper(settings: value, peer: EnginePeer(peer))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return (.users(users), .groups(groups), .channels(channels), .stories(stories))
|
|
}
|
|
|
|
func filteredGlobalSound(_ sound: PeerMessageSound) -> PeerMessageSound {
|
|
if case .default = sound {
|
|
return defaultCloudPeerNotificationSound
|
|
} else {
|
|
return sound
|
|
}
|
|
}
|
|
|
|
let presentNotificationCategorySettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, NotificationsPeerCategory, NotificationsPeerCategoryEntryTag?) -> Void = { context, present, category, itemTag in
|
|
let exceptionMode = exceptions()
|
|
let mode: NotificationExceptionMode
|
|
switch category {
|
|
case .privateChat:
|
|
mode = exceptionMode.0
|
|
case .group:
|
|
mode = exceptionMode.1
|
|
case .channel:
|
|
mode = exceptionMode.2
|
|
case .stories:
|
|
mode = exceptionMode.3
|
|
}
|
|
present(.push, notificationsPeerCategoryController(context: context, category: category, mode: mode, updatedMode: { _ in }, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
return [
|
|
SettingsSearchableItem(
|
|
id: "notifications",
|
|
title: strings.Settings_NotificationsAndSounds,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_Title),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, nil)
|
|
}
|
|
),
|
|
|
|
SettingsSearchableItem(
|
|
id: "notifications/accounts",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, .allAccounts)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/private-chats",
|
|
title: strings.Notifications_PrivateChats,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsSound),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications.capitalized],
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .privateChat, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/private-chats/edit",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_PrivateChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .privateChat, .edit)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/private-chats/show",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_PrivateChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .privateChat, .enable)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/private-chats/preview",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_PrivateChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .privateChat, .previews)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/private-chats/sound",
|
|
title: strings.Notifications_MessageNotificationsSound,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsSound),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_PrivateChats],
|
|
present: { context, _, present in
|
|
let controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.privateChats.sound), defaultSound: nil, completion: { value in
|
|
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
|
|
var settings = settings
|
|
settings.privateChats.sound = value
|
|
return settings
|
|
}).start()
|
|
})
|
|
present(.modal, controller)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/private-chats/add-exception",
|
|
title: strings.Notifications_MessageNotificationsExceptions,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsExceptions),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_PrivateChats],
|
|
present: { context, _, present in
|
|
present(.push, NotificationExceptionsController(context: context, mode: exceptions().0, updatedMode: { _ in}))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/private-chats/delete-exceptions",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_PrivateChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .privateChat, .deleteExceptions)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/groups",
|
|
title: strings.Notifications_GroupChats,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications.capitalized],
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .group, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/groups/edit",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .group, .edit)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/groups/show",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .group, .enable)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/groups/preview",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .group, .previews)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/groups/sound",
|
|
title: strings.Notifications_GroupNotificationsSound,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsSound),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupChats],
|
|
present: { context, _, present in
|
|
let controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.groupChats.sound), defaultSound: nil, completion: { value in
|
|
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
|
|
var settings = settings
|
|
settings.groupChats.sound = value
|
|
return settings
|
|
}).start()
|
|
})
|
|
present(.modal, controller)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/groups/add-exception",
|
|
title: strings.Notifications_GroupNotificationsExceptions,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_GroupNotificationsExceptions),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupChats],
|
|
present: { context, _, present in
|
|
present(.push, NotificationExceptionsController(context: context, mode: exceptions().1, updatedMode: { _ in}))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/groups/delete-exceptions",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_GroupChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .group, .deleteExceptions)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/channels",
|
|
title: strings.Notifications_Channels,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications.capitalized],
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .channel, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/channels/edit",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Channels],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .channel, .edit)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/channels/show",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Channels],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .channel, .enable)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/channels/preview",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Channels],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .channel, .previews)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/channels/sound",
|
|
title: strings.Notifications_ChannelNotificationsSound,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsSound),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Channels],
|
|
present: { context, _, present in
|
|
let controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.channels.sound), defaultSound: nil, completion: { value in
|
|
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
|
|
var settings = settings
|
|
settings.channels.sound = value
|
|
return settings
|
|
}).start()
|
|
})
|
|
present(.modal, controller)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/channels/add-exception",
|
|
title: strings.Notifications_MessageNotificationsExceptions,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ChannelNotificationsExceptions),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Channels],
|
|
present: { context, _, present in
|
|
present(.push, NotificationExceptionsController(context: context, mode: exceptions().2, updatedMode: { _ in}))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/channels/delete-exceptions",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Channels],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .channel, .deleteExceptions)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/stories",
|
|
title: strings.Notifications_Stories,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsSound),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_MessageNotifications.capitalized],
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .stories, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/stories/new",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Stories],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .stories, .enable)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/stories/important",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Stories],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .stories, .important)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/stories/show-sender",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Stories],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .stories, .previews)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/stories/sound",
|
|
title: strings.Notifications_MessageNotificationsSound,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Stories],
|
|
present: { context, _, present in
|
|
let controller = notificationSoundSelectionController(context: context, isModal: true, currentSound: filteredGlobalSound(settings.privateChats.storySettings.sound), defaultSound: nil, completion: { value in
|
|
let _ = updateGlobalNotificationSettingsInteractively(postbox: context.account.postbox, { settings in
|
|
var settings = settings
|
|
settings.privateChats.storySettings.sound = value
|
|
return settings
|
|
}).start()
|
|
})
|
|
present(.modal, controller)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/stories/add-exception",
|
|
title: strings.Notifications_MessageNotificationsExceptions,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_MessageNotificationsExceptions),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Stories],
|
|
present: { context, _, present in
|
|
present(.push, NotificationExceptionsController(context: context, mode: exceptions().3, updatedMode: { _ in}))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/stories/delete-exceptions",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Stories],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentNotificationCategorySettings(context, present, .stories, .deleteExceptions)
|
|
}
|
|
),
|
|
|
|
SettingsSearchableItem(
|
|
id: "notifications/reactions",
|
|
title: strings.Notifications_Reactions,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds],
|
|
present: { context, _, present in
|
|
present(.push, reactionNotificationSettingsController(context: context))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/reactions/messages",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Reactions],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, reactionNotificationSettingsController(context: context, focusOnItemTag: .messages))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/reactions/stories",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Reactions],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, reactionNotificationSettingsController(context: context, focusOnItemTag: .stories))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/reactions/show-sender",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Reactions],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, reactionNotificationSettingsController(context: context, focusOnItemTag: .showSender))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/reactions/sound",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Reactions],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, reactionNotificationSettingsController(context: context, focusOnItemTag: .sound))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/in-app-sounds",
|
|
title: strings.Notifications_InAppNotificationsSounds,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_InAppNotificationsSound),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_InAppNotifications.capitalized],
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, .inAppSounds)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/in-app-vibrate",
|
|
title: strings.Notifications_InAppNotificationsVibrate,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_InAppNotificationsVibrate),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_InAppNotifications.capitalized],
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, .inAppVibrate)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/in-app-preview",
|
|
title: strings.Notifications_InAppNotificationsPreview,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_InAppNotificationsPreview),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_InAppNotifications.capitalized],
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, .inAppPreviews)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/lock-screen-names",
|
|
title: strings.Notifications_DisplayNamesOnLockScreen,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_DisplayNamesOnLockScreen),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds],
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, .displayNamesOnLockscreen)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/include-channels",
|
|
title: strings.Notifications_Badge_IncludeChannels,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeIncludeMutedChannels),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge.capitalized],
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, .includeChannels)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/count-unread-messages",
|
|
title: strings.Notifications_Badge_CountUnreadMessages,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_BadgeCountUnreadMessages),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds, strings.Notifications_Badge.capitalized],
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, .unreadCountCategory)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/new-contacts",
|
|
title: strings.NotificationSettings_ContactJoined,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ContactJoined),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds],
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, .joinedNotifications)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "notifications/reset",
|
|
title: strings.Notifications_ResetAllNotifications,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Notifications_ResetAllNotifications),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_NotificationsAndSounds],
|
|
present: { context, _, present in
|
|
presentNotificationSettings(context, present, .reset)
|
|
}
|
|
)
|
|
]
|
|
}
|
|
|
|
private func privacySearchableItems(context: AccountContext, privacySettings: AccountPrivacySettings?, activeSessionsContext: ActiveSessionsContext?, webSessionsContext: WebSessionsContext?) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .privacy
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let presentPrivacySettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, PrivacyAndSecurityEntryTag?) -> Void = { context, present, itemTag in
|
|
present(.push, privacyAndSecurityController(context: context, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
let presentSelectivePrivacySettings: (AccountContext, SelectivePrivacySettingsKind, SelectivePrivacyEntryTag?, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, kind, focusOnItemTag, present in
|
|
let privacySignal: Signal<AccountPrivacySettings, NoError>
|
|
if let privacySettings = privacySettings {
|
|
privacySignal = .single(privacySettings)
|
|
} else {
|
|
privacySignal = context.engine.privacy.requestAccountPrivacySettings()
|
|
}
|
|
let callsSignal: Signal<(VoiceCallSettings, VoipConfiguration)?, NoError>
|
|
if case .voiceCalls = kind {
|
|
callsSignal = combineLatest(context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.voiceCallSettings]), context.account.postbox.preferencesView(keys: [PreferencesKeys.voipConfiguration]))
|
|
|> take(1)
|
|
|> map { sharedData, view -> (VoiceCallSettings, VoipConfiguration)? in
|
|
let voiceCallSettings: VoiceCallSettings = sharedData.entries[ApplicationSpecificSharedDataKeys.voiceCallSettings]?.get(VoiceCallSettings.self) ?? .defaultSettings
|
|
let voipConfiguration = view.values[PreferencesKeys.voipConfiguration]?.get(VoipConfiguration.self) ?? .defaultValue
|
|
return (voiceCallSettings, voipConfiguration)
|
|
}
|
|
} else {
|
|
callsSignal = .single(nil)
|
|
}
|
|
|
|
let _ = (combineLatest(privacySignal, callsSignal)
|
|
|> deliverOnMainQueue).start(next: { info, callSettings in
|
|
let current: SelectivePrivacySettings
|
|
switch kind {
|
|
case .presence:
|
|
current = info.presence
|
|
case .groupInvitations:
|
|
current = info.groupInvitations
|
|
case .voiceCalls:
|
|
current = info.voiceCalls
|
|
case .profilePhoto:
|
|
current = info.profilePhoto
|
|
case .forwards:
|
|
current = info.forwards
|
|
case .phoneNumber:
|
|
current = info.phoneNumber
|
|
case .voiceMessages:
|
|
current = info.voiceMessages
|
|
case .bio:
|
|
current = info.bio
|
|
case .birthday:
|
|
current = info.birthday
|
|
case .savedMusic:
|
|
current = info.savedMusic
|
|
case .giftsAutoSave:
|
|
current = info.giftsAutoSave
|
|
}
|
|
|
|
present(.push, selectivePrivacySettingsController(context: context, kind: kind, current: current, callSettings: callSettings != nil ? (info.voiceCallsP2P, callSettings!.0) : nil, voipConfiguration: callSettings?.1, callIntegrationAvailable: CallKitIntegration.isAvailable, focusOnItemTag: focusOnItemTag, updated: { updated, updatedCallSettings, _, _ in
|
|
if let (_, updatedCallSettings) = updatedCallSettings {
|
|
let _ = updateVoiceCallSettingsSettingsInteractively(accountManager: context.sharedContext.accountManager, { _ in
|
|
return updatedCallSettings
|
|
}).start()
|
|
}
|
|
}))
|
|
})
|
|
}
|
|
|
|
let presentMessagesPrivacySettings: (AccountContext, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void, IncomingMessagePrivacyEntryTag?) -> Void = { context, present, itemTag in
|
|
let privacySignal: Signal<AccountPrivacySettings, NoError>
|
|
if let privacySettings = privacySettings {
|
|
privacySignal = .single(privacySettings)
|
|
} else {
|
|
privacySignal = context.engine.privacy.requestAccountPrivacySettings()
|
|
}
|
|
|
|
let _ = (privacySignal
|
|
|> deliverOnMainQueue).start(next: { privacySettings in
|
|
let controller = incomingMessagePrivacyScreen(context: context, value: privacySettings.globalSettings.nonContactChatsPrivacy, exceptions: privacySettings.noPaidMessages, update: { settingValue in
|
|
let _ = (context.engine.privacy.updateNonContactChatsPrivacy(value: settingValue)
|
|
|> mapToSignal { _ -> Signal<Void, NoError> in }
|
|
|> deliverOnMainQueue).start()
|
|
}, focusOnItemTag: itemTag)
|
|
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
|
|
let presentMessageAutoRemove: (AccountContext, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void, GlobalAutoremoveEntryTag?) -> Void = { context, present, itemTag in
|
|
let privacySignal: Signal<AccountPrivacySettings, NoError>
|
|
if let privacySettings = privacySettings {
|
|
privacySignal = .single(privacySettings)
|
|
} else {
|
|
privacySignal = context.engine.privacy.requestAccountPrivacySettings()
|
|
}
|
|
let _ = (privacySignal
|
|
|> deliverOnMainQueue).start(next: { info in
|
|
let controller = globalAutoremoveScreen(context: context, initialValue: info.messageAutoremoveTimeout ?? 0, updated: { _ in }, focusOnItemTag: itemTag)
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
|
|
let presentDataPrivacySettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, DataPrivacyEntryTag?) -> Void = { context, present, itemTag in
|
|
present(.push, dataPrivacyController(context: context, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
let presentBlockUser: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void) -> Void = { context, present in
|
|
let blockedPeersContext = BlockedPeersContext(account: context.account, subject: .blocked)
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyPrivateChats, .excludeSavedMessages, .removeSearchHeader, .excludeRecent, .doNotSearchMessages], title: presentationData.strings.BlockedUsers_SelectUserTitle))
|
|
controller.peerSelected = { [weak controller] peer, _ in
|
|
let peerId = peer.id
|
|
|
|
guard let strongController = controller else {
|
|
return
|
|
}
|
|
strongController.inProgress = true
|
|
let _ = (blockedPeersContext.add(peerId: peerId)
|
|
|> deliverOnMainQueue).start(completed: {
|
|
guard let strongController = controller else {
|
|
return
|
|
}
|
|
strongController.inProgress = false
|
|
strongController.dismiss()
|
|
})
|
|
}
|
|
present(.push, controller)
|
|
}
|
|
|
|
let passcodeTitle: String
|
|
let passcodeAlternate: [String]
|
|
if let biometricAuthentication = LocalAuth.biometricAuthentication {
|
|
switch biometricAuthentication {
|
|
case .touchId:
|
|
passcodeTitle = strings.PrivacySettings_PasscodeAndTouchId
|
|
passcodeAlternate = synonyms(strings.SettingsSearch_Synonyms_Privacy_PasscodeAndTouchId)
|
|
case .faceId:
|
|
passcodeTitle = strings.PrivacySettings_PasscodeAndFaceId
|
|
passcodeAlternate = synonyms(strings.SettingsSearch_Synonyms_Privacy_PasscodeAndFaceId)
|
|
}
|
|
} else {
|
|
passcodeTitle = strings.PrivacySettings_Passcode
|
|
passcodeAlternate = synonyms(strings.SettingsSearch_Synonyms_Privacy_Passcode)
|
|
}
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy",
|
|
title: strings.Settings_PrivacySettings,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Title),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
presentPrivacySettings(context, present, nil)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/blocked",
|
|
title: strings.Settings_BlockedUsers,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_BlockedUsers),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
present(.push, blockedPeersController(context: context, blockedPeersContext: BlockedPeersContext(account: context.account, subject: .blocked)))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/blocked/edit",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Settings_BlockedUsers],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, blockedPeersController(context: context, blockedPeersContext: BlockedPeersContext(account: context.account, subject: .blocked), forceEdit: true))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/blocked/block-user",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Settings_BlockedUsers],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentBlockUser(context, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/blocked/block-user/chats",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Settings_BlockedUsers],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentBlockUser(context, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/blocked/block-user/contacts",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Settings_BlockedUsers],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentBlockUser(context, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/last-seen",
|
|
title: strings.PrivacySettings_LastSeen,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_LastSeen),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .presence, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/last-seen/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_LastSeen],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .presence, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/last-seen/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_LastSeen],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .presence, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/last-seen/hide-read-time",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_LastSeen],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .presence, .lastSeenHideReadTime, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/profile-photos",
|
|
title: strings.Privacy_ProfilePhoto,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_ProfilePhoto),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .profilePhoto, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/profile-photos/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_ProfilePhoto],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .profilePhoto, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/profile-photos/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_ProfilePhoto],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .profilePhoto, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/profile-photos/set-public",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_ProfilePhoto],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .profilePhoto, .photoSetPublic, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/profile-photos/update-public",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_ProfilePhoto],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .profilePhoto, .photoUpdatePublic, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/profile-photos/remove-public",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_ProfilePhoto],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .profilePhoto, .photoRemovePublic, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/forwards",
|
|
title: strings.Privacy_Forwards,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Forwards),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .forwards, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/forwards/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Forwards],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .forwards, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/forwards/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Forwards],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .forwards, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/calls",
|
|
title: strings.Privacy_Calls,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Calls),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceCalls, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/calls/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Calls],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceCalls, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/calls/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Calls],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceCalls, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/calls/p2p",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Calls],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceCalls, .callsP2P, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/calls/p2p/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Calls],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceCalls, .callsP2PNeverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/calls/p2p/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Calls],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceCalls, .callsP2PAlwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/calls/ios-integration",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Calls],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceCalls, .callsIntegration, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/invites",
|
|
title: strings.Privacy_GroupsAndChannels,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_GroupsAndChannels),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .groupInvitations, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/invites/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_GroupsAndChannels],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .groupInvitations, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/invites/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_GroupsAndChannels],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .groupInvitations, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/bio",
|
|
title: strings.Privacy_Bio,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .bio, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/bio/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Bio],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .bio, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/bio/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Bio],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .bio, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/birthday",
|
|
title: strings.Privacy_Birthday,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .birthday, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/birthday/add",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Birthday],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSetupBirthday(context: context, present: present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/birthday/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Birthday],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .birthday, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/birthday/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Birthday],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .birthday, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/gifts",
|
|
title: strings.Privacy_Gifts,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .giftsAutoSave, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/gifts/show-icon",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Gifts],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .giftsAutoSave, .giftsShowButton, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/gifts/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Gifts],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .giftsAutoSave, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/gifts/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Gifts],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .giftsAutoSave, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/gifts/accepted-types",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_Gifts],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .giftsAutoSave, .giftsAcceptedTypes, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/phone-number",
|
|
title: strings.Privacy_PhoneNumber,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .phoneNumber, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/phone-number/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_PhoneNumber],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .phoneNumber, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/phone-number/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_PhoneNumber],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .phoneNumber, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/saved-music",
|
|
title: strings.Privacy_SavedMusic,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .savedMusic, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/saved-music/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_SavedMusic],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .savedMusic, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/saved-music/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_SavedMusic],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .savedMusic, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/voice",
|
|
title: strings.Privacy_VoiceMessages,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceMessages, nil, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/voice/never",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_VoiceMessages],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceMessages, .neverAllow, present)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/voice/always",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Privacy_VoiceMessages],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSelectivePrivacySettings(context, .voiceMessages, .alwaysAllow, present)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/messages",
|
|
title: strings.Settings_Privacy_Messages,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentMessagesPrivacySettings(context, present, nil)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/messages/set-price",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Settings_Privacy_Messages],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentMessagesPrivacySettings(context, present, .setPrice)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/messages/remove-fee",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Settings_Privacy_Messages],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentMessagesPrivacySettings(context, present, .removeFee)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/passcode",
|
|
title: passcodeTitle,
|
|
alternate: passcodeAlternate,
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
let _ = passcodeOptionsAccessController(context: context, pushController: { c in
|
|
present(.push, c)
|
|
}, completion: { animated in
|
|
let controller = passcodeOptionsController(context: context)
|
|
present(.push, controller)
|
|
}).start(next: { controller in
|
|
if let controller {
|
|
present(.push, controller)
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/passcode/disable",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, passcodeTitle],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let _ = passcodeOptionsAccessController(context: context, pushController: { c in
|
|
present(.push, c)
|
|
}, completion: { animated in
|
|
let controller = passcodeOptionsController(context: context, focusOnItemTag: .togglePasscode)
|
|
present(.push, controller)
|
|
}).start(next: { controller in
|
|
if let controller {
|
|
present(.push, controller)
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/passcode/change",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, passcodeTitle],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let _ = passcodeOptionsAccessController(context: context, pushController: { c in
|
|
present(.push, c)
|
|
}, completion: { animated in
|
|
let controller = passcodeOptionsController(context: context, focusOnItemTag: .changePasscode)
|
|
present(.push, controller)
|
|
}).start(next: { controller in
|
|
if let controller {
|
|
present(.push, controller)
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/passcode/auto-lock",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, passcodeTitle],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let _ = passcodeOptionsAccessController(context: context, pushController: { c in
|
|
present(.push, c)
|
|
}, completion: { animated in
|
|
let controller = passcodeOptionsController(context: context, focusOnItemTag: .autolock)
|
|
present(.push, controller)
|
|
}).start(next: { controller in
|
|
if let controller {
|
|
present(.push, controller)
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/passcode/face-id",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, passcodeTitle],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let _ = passcodeOptionsAccessController(context: context, pushController: { c in
|
|
present(.push, c)
|
|
}, completion: { animated in
|
|
let controller = passcodeOptionsController(context: context, focusOnItemTag: .touchId)
|
|
present(.push, controller)
|
|
}).start(next: { controller in
|
|
if let controller {
|
|
present(.push, controller)
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/2sv",
|
|
title: strings.PrivacySettings_TwoStepAuth,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_TwoStepAuth),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
present(.push, twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: true, data: nil)))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/2sv/change",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_TwoStepAuth],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: true, data: nil), focusOnItemTag: .change))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/2sv/disable",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_TwoStepAuth],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: true, data: nil), focusOnItemTag: .disable))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/2sv/change-email",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_TwoStepAuth],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, twoStepVerificationUnlockSettingsController(context: context, mode: .access(intro: true, data: nil), focusOnItemTag: .changeEmail))
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/passkey",
|
|
title: strings.PrivacySettings_Passkey,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
Task { @MainActor in
|
|
let initialPasskeysData = await (context.engine.auth.passkeysData() |> take(1)).get()
|
|
let passkeysScreen = PasskeysScreen(context: context, displaySkip: false, initialPasskeysData: initialPasskeysData, passkeysDataUpdated: { _ in
|
|
}, completion: {}, cancel: {})
|
|
present(.push, passkeysScreen)
|
|
}
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/passkey/create",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_Passkey],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
Task { @MainActor in
|
|
let initialPasskeysData = await (context.engine.auth.passkeysData() |> take(1)).get()
|
|
let passkeysScreen = PasskeysScreen(context: context, displaySkip: false, initialPasskeysData: initialPasskeysData, forceCreate: true, passkeysDataUpdated: { _ in
|
|
}, completion: {}, cancel: {})
|
|
present(.push, passkeysScreen)
|
|
}
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/auto-delete",
|
|
title: strings.Settings_AutoDeleteTitle,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentMessageAutoRemove(context, present, nil)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/auto-delete/set-custom",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.Settings_AutoDeleteTitle],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentMessageAutoRemove(context, present, .setCustom)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/login-email",
|
|
title: strings.PrivacySettings_LoginEmail,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, navigationController, present in
|
|
let settingsPromise: Promise<TwoStepAuthData?>
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface, let current = rootController.getTwoStepAuthData() {
|
|
settingsPromise = current
|
|
} else {
|
|
settingsPromise = Promise()
|
|
settingsPromise.set(
|
|
context.engine.auth.twoStepAuthData()
|
|
|> map(Optional.init)
|
|
|> `catch` { _ -> Signal<TwoStepAuthData?, NoError> in
|
|
return .single(nil)
|
|
}
|
|
)
|
|
}
|
|
|
|
let _ = (settingsPromise.get()
|
|
|> take(1)
|
|
|> deliverOnMainQueue).start(next: { twoStepAuthData in
|
|
let emailPattern = twoStepAuthData?.loginEmailPattern
|
|
let setupEmailImpl: (String?) -> Void = { emailPattern in
|
|
let controller = loginEmailSetupController(context: context, blocking: false, emailPattern: nil, navigationController: navigationController, completion: {}, dismiss: {})
|
|
present(.push, controller)
|
|
}
|
|
if let emailPattern, !emailPattern.contains(" ") {
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
let controller = textAlertController(
|
|
context: context, title: emailPattern, text: presentationData.strings.PrivacySettings_LoginEmailAlertText, actions: [
|
|
TextAlertAction(type: .defaultAction, title: presentationData.strings.PrivacySettings_LoginEmailAlertChange, action: {
|
|
setupEmailImpl(emailPattern)
|
|
}),
|
|
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
|
})
|
|
], actionLayout: .vertical
|
|
)
|
|
present(.immediate, controller)
|
|
} else {
|
|
setupEmailImpl(nil)
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
if let webSessionsContext {
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/active-websites",
|
|
title: strings.PrivacySettings_WebSessions,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_AuthSessions),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext ?? context.engine.privacy.activeSessions(), webSessionsContext: webSessionsContext, websitesOnly: true))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/active-websites/edit",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext ?? context.engine.privacy.activeSessions(), webSessionsContext: webSessionsContext, websitesOnly: true, focusOnItemTag: .edit))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/active-websites/disconnect-all",
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, recentSessionsController(context: context, activeSessionsContext: activeSessionsContext ?? context.engine.privacy.activeSessions(), webSessionsContext: webSessionsContext, websitesOnly: true, focusOnItemTag: .terminateOtherSessions))
|
|
}
|
|
)
|
|
)
|
|
}
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/self-destruct",
|
|
title: strings.PrivacySettings_DeleteAccountTitle.capitalized,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_DeleteAccountIfAwayFor),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentPrivacySettings(context, present, .accountTimeout)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/archive-and-mute",
|
|
title: strings.PrivacySettings_AutoArchive,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentPrivacySettings(context, present, .autoArchive)
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/data-settings",
|
|
title: strings.PrivacySettings_DataSettings,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Data_Title),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings],
|
|
present: { context, _, present in
|
|
presentDataPrivacySettings(context, present, nil)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/data-settings/delete-synced",
|
|
title: strings.Privacy_ContactsReset,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Data_ContactsReset),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_DataSettings],
|
|
present: { context, _, present in
|
|
presentDataPrivacySettings(context, present, .deleteSynced)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/data-settings/sync-contacts",
|
|
title: strings.Privacy_ContactsSync,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Data_ContactsSync),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_DataSettings],
|
|
present: { context, _, present in
|
|
presentDataPrivacySettings(context, present, .syncContacts)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/data-settings/suggest-contacts",
|
|
title: strings.Privacy_TopPeers,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Data_TopPeers),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_DataSettings],
|
|
present: { context, _, present in
|
|
presentDataPrivacySettings(context, present, .suggestContacts)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/data-settings/delete-cloud-drafts",
|
|
title: strings.Privacy_DeleteDrafts,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Data_DeleteDrafts),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_DataSettings],
|
|
present: { context, _, present in
|
|
presentDataPrivacySettings(context, present, .deleteCloudDrafts)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/data-settings/clear-payment-info",
|
|
title: strings.Privacy_PaymentsClearInfo,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Data_ClearPaymentsInfo),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_DataSettings],
|
|
present: { context, _, present in
|
|
presentDataPrivacySettings(context, present, .clearPaymentInfo)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/data-settings/link-previews",
|
|
title: strings.Privacy_SecretChatsLinkPreviews,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_Data_SecretChatLinkPreview),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_DataSettings, strings.Privacy_SecretChatsTitle.capitalized],
|
|
present: { context, _, present in
|
|
presentDataPrivacySettings(context, present, .linkPreviews)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy/data-settings/bot-settings",
|
|
title: strings.Settings_BotListSettings,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_PrivacySettings, strings.PrivacySettings_DataSettings],
|
|
present: { context, _, present in
|
|
let controller = context.sharedContext.makeBotSettingsScreen(context: context, peerId: nil)
|
|
present(.push, controller)
|
|
}
|
|
)
|
|
)
|
|
return items
|
|
}
|
|
|
|
private func dataSearchableItems(context: AccountContext) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .data
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let presentDataSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, DataAndStorageEntryTag?) -> Void = { context, present, itemTag in
|
|
present(.push, dataAndStorageController(context: context, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
let presentDataUsage: (AccountContext, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void, DataUsageEntryTag?) -> Void = { context, present, itemTag in
|
|
let mediaAutoDownloadSettings = context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings])
|
|
|> map { sharedData -> MediaAutoDownloadSettings in
|
|
var automaticMediaDownloadSettings: MediaAutoDownloadSettings
|
|
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings]?.get(MediaAutoDownloadSettings.self) {
|
|
automaticMediaDownloadSettings = value
|
|
} else {
|
|
automaticMediaDownloadSettings = .defaultSettings
|
|
}
|
|
return automaticMediaDownloadSettings
|
|
}
|
|
|
|
let _ = (combineLatest(
|
|
accountNetworkUsageStats(account: context.account, reset: []),
|
|
mediaAutoDownloadSettings
|
|
)
|
|
|> take(1)
|
|
|> deliverOnMainQueue).start(next: { stats, mediaAutoDownloadSettings in
|
|
var stats = stats
|
|
|
|
if stats.resetWifiTimestamp == 0 {
|
|
var value = stat()
|
|
if stat(context.account.basePath, &value) == 0 {
|
|
stats.resetWifiTimestamp = Int32(value.st_ctimespec.tv_sec)
|
|
}
|
|
}
|
|
|
|
present(.push, DataUsageScreen(context: context, stats: stats, mediaAutoDownloadSettings: mediaAutoDownloadSettings, makeAutodownloadSettingsController: { isCellular in
|
|
return autodownloadMediaConnectionTypeController(context: context, connectionType: isCellular ? .cellular : .wifi)
|
|
}, focusOnItemTag: itemTag))
|
|
})
|
|
}
|
|
|
|
let presentStorageUsage: (AccountContext, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void, StorageUsageEntryTag?) -> Void = { context, present, itemTag in
|
|
let controller = StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
|
return storageUsageExceptionsScreen(context: context, category: category)
|
|
}, focusOnItemTag: itemTag)
|
|
present(.push, controller)
|
|
}
|
|
|
|
let presentSaveIncomingMediaSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, AutomaticSaveIncomingPeerType, SaveIncomingMediaEntryTag?) -> Void = { context, present, peerType, itemTag in
|
|
present(.push, saveIncomingMediaController(context: context, scope: .peerType(peerType), focusOnItemTag: itemTag))
|
|
}
|
|
|
|
let presentAutodownloadMediaSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, AutomaticDownloadConnectionType, AutodownloadMediaCategoryEntryTag?) -> Void = { context, present, connectionType, itemTag in
|
|
present(.push, autodownloadMediaConnectionTypeController(context: context, connectionType: connectionType, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
return [
|
|
SettingsSearchableItem(
|
|
id: "data",
|
|
title: strings.Settings_ChatSettings,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Title),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
presentDataSettings(context, present, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/storage",
|
|
title: strings.ChatSettings_Cache,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Storage_Title),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings],
|
|
present: { context, _, present in
|
|
presentStorageUsage(context, present, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/storage/edit",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_Cache],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentStorageUsage(context, present, .edit)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/storage/auto-remove",
|
|
title: strings.Cache_KeepMedia,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Storage_KeepMedia),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_Cache],
|
|
present: { context, _, present in
|
|
presentStorageUsage(context, present, .autoRemove)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/storage/clear-cache",
|
|
title: strings.Cache_ClearCache,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Storage_ClearCache),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_Cache],
|
|
present: { context, _, present in
|
|
presentStorageUsage(context, present, .clearCache)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/max-cache",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_Cache],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentStorageUsage(context, present, .maxCache)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/usage",
|
|
title: strings.NetworkUsageSettings_Title,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_NetworkUsage),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings],
|
|
present: { context, _, present in
|
|
presentDataUsage(context, present, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/usage/mobile",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentDataUsage(context, present, .mobile)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/usage/wifi",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentDataUsage(context, present, .wifi)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/usage/reset",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentDataUsage(context, present, .reset)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/mobile",
|
|
title: strings.ChatSettings_AutoDownloadUsingCellular,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadUsingCellular),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized],
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .cellular, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/mobile/enable",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .cellular, .master)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/mobile/usage",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .cellular, .usage)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/mobile/photos",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .cellular, .photos)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/mobile/stories",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .cellular, .stories)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/mobile/videos",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .cellular, .videos)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/mobile/files",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .cellular, .files)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/wifi",
|
|
title: strings.ChatSettings_AutoDownloadUsingWiFi,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadUsingWifi),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized],
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .wifi, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/wifi/enable",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .wifi, .master)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/wifi/usage",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .wifi, .usage)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/wifi/photos",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .wifi, .photos)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/wifi/stories",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .wifi, .stories)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/wifi/videos",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .wifi, .videos)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/wifi/files",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle.capitalized, strings.ChatSettings_AutoDownloadUsingCellular],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAutodownloadMediaSettings(context, present, .wifi, .files)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/auto-download/reset",
|
|
title: strings.ChatSettings_AutoDownloadReset,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadReset),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings],
|
|
present: { context, _, present in
|
|
presentDataSettings(context, present, .automaticDownloadReset)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/chats",
|
|
title: strings.Notifications_PrivateChats,
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .privateChats, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/chats/max-video-size",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection, strings.Notifications_PrivateChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .privateChats, .maxVideoSize)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/chats/add-exception",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection, strings.Notifications_PrivateChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .privateChats, .addException)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/chats/delete-all",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection, strings.Notifications_PrivateChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .privateChats, .deleteExceptions)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/groups",
|
|
title: strings.Notifications_GroupChats,
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .groups, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/groups/max-video-size",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection, strings.Notifications_GroupChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .groups, .maxVideoSize)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/groups/add-exception",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection, strings.Notifications_GroupChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .groups, .addException)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/groups/delete-all",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection, strings.Notifications_GroupChats],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .groups, .deleteExceptions)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/channels",
|
|
title: strings.Notifications_Channels,
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .channels, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/channels/max-video-size",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection, strings.Notifications_Channels],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .channels, .maxVideoSize)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/channels/add-exception",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection, strings.Notifications_Channels],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .channels, .addException)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-to-photos/channels/delete-all",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_SaveToCameraRollSection, strings.Notifications_Channels],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentSaveIncomingMediaSettings(context, present, .channels, .deleteExceptions)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/use-less-data",
|
|
title: strings.CallSettings_UseLessData,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_CallsUseLessData),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.Settings_CallSettings],
|
|
present: { context, _, present in
|
|
presentDataSettings(context, present, .useLessVoiceData)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/save-edited-photos",
|
|
title: strings.Settings_SaveEditedPhotos,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Data_SaveEditedPhotos),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings],
|
|
present: { context, _, present in
|
|
presentDataSettings(context, present, .saveEditedPhotos)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/pause-music",
|
|
title: strings.Settings_PauseMusicOnRecording,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings],
|
|
present: { context, _, present in
|
|
presentDataSettings(context, present, .pauseMusicOnRecording)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/raise-to-listen",
|
|
title: strings.Settings_RaiseToListen,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings],
|
|
present: { context, _, present in
|
|
presentDataSettings(context, present, .raiseToListen)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/show-18-content",
|
|
title: strings.Settings_SensitiveContent,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentDataSettings(context, present, .sensitiveContent)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/open-links",
|
|
title: strings.ChatSettings_OpenLinksIn,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_ChatSettings_OpenLinksIn),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings],
|
|
present: { context, _, present in
|
|
present(.push, webBrowserSettingsController(context: context))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/share-sheet",
|
|
title: strings.ChatSettings_IntentsSettings,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_ChatSettings_IntentsSettings),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings],
|
|
present: { context, _, present in
|
|
present(.push, intentsSettingsController(context: context))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/share-sheet/suggested-chats",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_IntentsSettings],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, intentsSettingsController(context: context, focusOnItemTag: .suggested))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/share-sheet/suggest-by",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_IntentsSettings],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, intentsSettingsController(context: context, focusOnItemTag: .suggestBy))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "data/share-sheet/reset",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_IntentsSettings],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, intentsSettingsController(context: context, focusOnItemTag: .reset))
|
|
}
|
|
)
|
|
]
|
|
}
|
|
|
|
private func proxySearchableItems(context: AccountContext, servers: [ProxyServerSettings]) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .proxy
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let presentProxySettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, ProxySettingsEntryTag?) -> Void = { context, present, itemTag in
|
|
present(.push, proxySettingsController(context: context, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "data/proxy",
|
|
title: strings.Settings_Proxy,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Proxy_Title),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
presentProxySettings(context, present, nil)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "data/proxy/edit",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentProxySettings(context, present, .edit)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "data/use-proxy",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentProxySettings(context, present, .useProxy)
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "data/proxy/add-proxy",
|
|
title: strings.SocksProxySetup_AddProxy,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Proxy_AddProxy),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Proxy],
|
|
present: { context, _, present in
|
|
present(.modal, proxyServerSettingsController(context: context))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "data/proxy/share-list",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentProxySettings(context, present, .shareList)
|
|
}
|
|
)
|
|
)
|
|
|
|
var hasSocksServers = false
|
|
for server in servers {
|
|
if case .socks5 = server.connection {
|
|
hasSocksServers = true
|
|
break
|
|
}
|
|
}
|
|
if hasSocksServers {
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "data/proxy/use-for-calls",
|
|
title: strings.SocksProxySetup_UseForCalls,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Proxy_UseForCalls),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Proxy],
|
|
present: { context, _, present in
|
|
presentProxySettings(context, present, .useForCalls)
|
|
}
|
|
)
|
|
)
|
|
}
|
|
return items
|
|
}
|
|
|
|
private func energySavingSearchableItems(context: AccountContext) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .powerSaving
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let presentEnergySaving: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, EnergySavingItemType?) -> Void = { context, present, item in
|
|
let controller = energySavingSettingsScreen(context: context, focusOnItemTag: item.flatMap { .item($0) })
|
|
present(.push, controller)
|
|
}
|
|
|
|
return [
|
|
SettingsSearchableItem(
|
|
id: "power-saving",
|
|
title: strings.Settings_PowerSaving,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
presentEnergySaving(context, present, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "power-saving/videos",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentEnergySaving(context, present, .autoplayVideo)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "power-saving/gifs",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentEnergySaving(context, present, .autoplayGif)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "power-saving/stickers",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentEnergySaving(context, present, .loopStickers)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "power-saving/emoji",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentEnergySaving(context, present, .loopEmoji)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "power-saving/effects",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentEnergySaving(context, present, .fullTranslucency)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "power-saving/preload",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentEnergySaving(context, present, .autodownloadInBackground)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "power-saving/background",
|
|
icon: icon,
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentEnergySaving(context, present, .extendBackgroundWork)
|
|
}
|
|
),
|
|
]
|
|
}
|
|
|
|
private func appearanceSearchableItems(context: AccountContext) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .appearance
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let presentAppearanceSettings: (AccountContext, (SettingsSearchableItemPresentation, ViewController?) -> Void, ThemeSettingsEntryTag?) -> Void = { context, present, itemTag in
|
|
present(.push, themeSettingsController(context: context, focusOnItemTag: itemTag))
|
|
}
|
|
|
|
var items: [SettingsSearchableItem] = [
|
|
SettingsSearchableItem(
|
|
id: "appearance",
|
|
title: strings.Settings_Appearance,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_Title),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
presentAppearanceSettings(context, present, nil)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/wallpapers",
|
|
title: strings.Settings_ChatBackground,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_ChatBackground),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
present: { context, _, present in
|
|
present(.push, ThemeGridController(context: context))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/wallpapers/edit",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance, strings.Settings_ChatBackground],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
present(.push, ThemeGridController(context: context, forceEdit: true))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/wallpapers/set",
|
|
title: strings.Wallpaper_SetColor,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_ChatBackground_SetColor),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance, strings.Settings_ChatBackground],
|
|
present: { context, _, present in
|
|
|
|
present(.push, ThemeColorsGridController(context: context))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/wallpapers/choose-photo",
|
|
title: strings.Wallpaper_SetCustomBackground,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_ChatBackground_Custom),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance, strings.Settings_ChatBackground],
|
|
present: { context, _, present in
|
|
presentCustomWallpaperPicker(context: context, present: { controller in
|
|
present(.immediate, controller)
|
|
}, push: { controller in
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/night-mode",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAppearanceSettings(context, present, .nightMode)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/auto-night-mode",
|
|
title: strings.Appearance_AutoNightTheme,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_AutoNightTheme),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
present: { context, _, present in
|
|
present(.push, themeAutoNightSettingsController(context: context))
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/themes",
|
|
title: strings.Themes_Title,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_ColorTheme),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
present: { context, _, present in
|
|
let controller = themePickerController(context: context)
|
|
present(.push, controller)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/themes/edit",
|
|
title: strings.Themes_EditCurrentTheme,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance, strings.Themes_Title],
|
|
present: { context, _, present in
|
|
let controller = themePickerController(context: context)
|
|
present(.push, controller)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/themes/create",
|
|
title: strings.Themes_CreateNewTheme,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance, strings.Themes_Title],
|
|
present: { context, navigationController, present in
|
|
let _ = (context.sharedContext.accountManager.transaction { transaction -> PresentationThemeReference in
|
|
let settings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.presentationThemeSettings)?.get(PresentationThemeSettings.self) ?? PresentationThemeSettings.defaultSettings
|
|
|
|
let themeReference: PresentationThemeReference
|
|
let autoNightModeTriggered = context.sharedContext.currentPresentationData.with { $0 }.autoNightModeTriggered
|
|
if autoNightModeTriggered {
|
|
themeReference = settings.automaticThemeSwitchSetting.theme
|
|
} else {
|
|
themeReference = settings.theme
|
|
}
|
|
|
|
return themeReference
|
|
}
|
|
|> deliverOnMainQueue).start(next: { [weak navigationController] themeReference in
|
|
let controller = editThemeController(context: context, mode: .create(nil, nil), navigateToChat: { [weak navigationController] peerId in
|
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
|
|> deliverOnMainQueue).start(next: { [weak navigationController] peer in
|
|
guard let peer else {
|
|
return
|
|
}
|
|
if let navigationController {
|
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
|
}
|
|
})
|
|
})
|
|
present(.push, controller)
|
|
})
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/text-size",
|
|
title: strings.Appearance_TextSizeSetting,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Appearance_TextSize),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
present: { context, _, present in
|
|
let _ = (context.sharedContext.accountManager.sharedData(keys: Set([ApplicationSpecificSharedDataKeys.presentationThemeSettings]))
|
|
|> take(1)
|
|
|> deliverOnMainQueue).start(next: { view in
|
|
let settings = view.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings]?.get(PresentationThemeSettings.self) ?? PresentationThemeSettings.defaultSettings
|
|
present(.push, TextSizeSelectionController(context: context, presentationThemeSettings: settings))
|
|
})
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/text-size/use-system",
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
let _ = (context.sharedContext.accountManager.sharedData(keys: Set([ApplicationSpecificSharedDataKeys.presentationThemeSettings]))
|
|
|> take(1)
|
|
|> deliverOnMainQueue).start(next: { view in
|
|
let settings = view.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings]?.get(PresentationThemeSettings.self) ?? PresentationThemeSettings.defaultSettings
|
|
present(.push, TextSizeSelectionController(context: context, presentationThemeSettings: settings, focusOnItemTag: .useSystem))
|
|
})
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/message-corners",
|
|
title: strings.Appearance_BubbleCornersSetting,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
present: { context, _, present in
|
|
let _ = (context.sharedContext.accountManager.sharedData(keys: Set([ApplicationSpecificSharedDataKeys.presentationThemeSettings]))
|
|
|> take(1)
|
|
|> deliverOnMainQueue).start(next: { view in
|
|
let settings = view.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings]?.get(PresentationThemeSettings.self) ?? PresentationThemeSettings.defaultSettings
|
|
present(.push, BubbleSettingsController(context: context, presentationThemeSettings: settings))
|
|
})
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/app-icon",
|
|
title: strings.Appearance_AppIcon.capitalized,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
present: { context, _, present in
|
|
presentAppearanceSettings(context, present, .icon)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/animations",
|
|
title: strings.Appearance_Animations.capitalized,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
present: { context, _, present in
|
|
let controller = energySavingSettingsScreen(context: context)
|
|
present(.push, controller)
|
|
}
|
|
),
|
|
SettingsSearchableItem(
|
|
id: "appearance/tap-for-next-media",
|
|
title: strings.Appearance_ShowNextMediaOnTap,
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAppearanceSettings(context, present, .tapForNextMedia)
|
|
}
|
|
)
|
|
]
|
|
|
|
if DeviceModel.current.isIpad {
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "appearance/send-with-cmd-enter",
|
|
title: strings.Appearance_SendWithCmdEnter,
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_Appearance],
|
|
isVisible: false,
|
|
present: { context, _, present in
|
|
presentAppearanceSettings(context, present, .sendWithCmdEnter)
|
|
}
|
|
)
|
|
)
|
|
}
|
|
return items
|
|
}
|
|
|
|
private func languageSearchableItems(context: AccountContext, localizations: [LocalizationInfo]) -> [SettingsSearchableItem] {
|
|
let icon: SettingsSearchableItemIcon = .language
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
let applyLocalization: (AccountContext, @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void, String) -> Void = { context, present, languageCode in
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
|
|
present(.immediate, controller)
|
|
|
|
let _ = (context.engine.localization.downloadAndApplyLocalization(accountManager: context.sharedContext.accountManager, languageCode: languageCode)
|
|
|> deliverOnMainQueue).start(completed: { [weak controller] in
|
|
controller?.dismiss()
|
|
present(.dismiss, nil)
|
|
})
|
|
}
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "language",
|
|
title: strings.Settings_AppLanguage,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_AppLanguage),
|
|
icon: icon,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
present(.push, LocalizationListController(context: context))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "language/show-button",
|
|
title: strings.Localization_ShowTranslate,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Language_ShowTranslateButton),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_AppLanguage],
|
|
present: { context, _, present in
|
|
present(.push, LocalizationListController(context: context, focusOnItemTag: .showButton))
|
|
}
|
|
)
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "language/translate-chats",
|
|
title: strings.Localization_TranslateEntireChat,
|
|
alternate: [],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_AppLanguage],
|
|
present: { context, _, present in
|
|
present(.push, LocalizationListController(context: context, focusOnItemTag: .translateChats))
|
|
})
|
|
)
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "language/do-not-translate",
|
|
title: strings.Localization_DoNotTranslate,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Language_DoNotTranslate),
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_AppLanguage],
|
|
present: { context, _, present in
|
|
present(.push, translationSettingsController(context: context))
|
|
})
|
|
)
|
|
|
|
var index: Int32 = 1
|
|
for localization in localizations {
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "language/set/\(localization.languageCode)",
|
|
title: localization.localizedTitle,
|
|
alternate: [localization.title],
|
|
icon: icon,
|
|
breadcrumbs: [strings.Settings_AppLanguage],
|
|
present: { context, _, present in
|
|
applyLocalization(context, present, localization.languageCode)
|
|
}
|
|
)
|
|
)
|
|
index += 1
|
|
}
|
|
|
|
return items
|
|
}
|
|
|
|
private func helpSearchableItems(context: AccountContext) -> [SettingsSearchableItem] {
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
let strings = presentationData.strings
|
|
|
|
var items: [SettingsSearchableItem] = []
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "ask-question",
|
|
title: strings.Settings_Support,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Support),
|
|
icon: .support,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
let _ = (context.engine.peers.supportPeerId()
|
|
|> deliverOnMainQueue).start(next: { peerId in
|
|
if let peerId = peerId {
|
|
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil))
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "faq",
|
|
title: strings.Settings_FAQ,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_FAQ),
|
|
icon: .faq,
|
|
breadcrumbs: [],
|
|
present: { context, navigationController, present in
|
|
let _ = (cachedFaqInstantPage(context: context)
|
|
|> take(1)
|
|
|> deliverOnMainQueue).start(next: { resolvedUrl in
|
|
context.sharedContext.openResolvedUrl(resolvedUrl, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, forceUpdate: false, openPeer: { peer, navigation in
|
|
}, sendFile: nil, sendSticker: nil, sendEmoji: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { controller, arguments in
|
|
present(.push, controller)
|
|
}, dismissInput: {}, contentContext: nil, progress: nil, completion: nil)
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "features",
|
|
title: strings.Settings_Tips,
|
|
alternate: [],
|
|
icon: .tips,
|
|
breadcrumbs: [],
|
|
present: { context, navigationController, present in
|
|
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
|
|
present(.immediate, controller)
|
|
|
|
let _ = (context.engine.peers.resolvePeerByName(name: strings.Settings_TipsUsername, referrer: nil)
|
|
|> mapToSignal { result -> Signal<EnginePeer?, NoError> in
|
|
guard case let .result(result) = result else {
|
|
return .complete()
|
|
}
|
|
return .single(result)
|
|
}
|
|
|> deliverOnMainQueue).startStandalone(next: { [weak controller] peer in
|
|
controller?.dismiss()
|
|
if let peer, let navigationController {
|
|
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(peer)))
|
|
}
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
items.append(
|
|
SettingsSearchableItem(
|
|
id: "privacy-policy",
|
|
title: strings.Permissions_PrivacyPolicy,
|
|
alternate: [],
|
|
icon: .tips,
|
|
breadcrumbs: [],
|
|
present: { context, navigationController, present in
|
|
let _ = (cachedPrivacyPage(context: context)
|
|
|> take(1)
|
|
|> deliverOnMainQueue).start(next: { resolvedUrl in
|
|
context.sharedContext.openResolvedUrl(resolvedUrl, context: context, urlContext: .generic, navigationController: navigationController, forceExternal: false, forceUpdate: false, openPeer: { peer, navigation in
|
|
}, sendFile: nil, sendSticker: nil, sendEmoji: nil, requestMessageActionUrlAuth: nil, joinVoiceChat: nil, present: { c, arguments in
|
|
present(.push, c)
|
|
}, dismissInput: {}, contentContext: nil, progress: nil, completion: nil)
|
|
})
|
|
}
|
|
)
|
|
)
|
|
|
|
return items
|
|
}
|
|
|
|
func settingsSearchableItems(
|
|
context: AccountContext,
|
|
notificationExceptionsList: Signal<NotificationExceptionsList?, NoError> = .single(nil),
|
|
archivedStickerPacks: Signal<[ArchivedStickerPackItem]?, NoError> = .single(nil),
|
|
privacySettings: Signal<AccountPrivacySettings?, NoError> = .single(nil),
|
|
hasTwoStepAuth: Signal<Bool?, NoError> = .single(nil),
|
|
twoStepAuthData: Signal<TwoStepVerificationAccessConfiguration?, NoError> = .single(nil),
|
|
activeSessionsContext: Signal<ActiveSessionsContext?, NoError> = .single(nil),
|
|
webSessionsContext: Signal<WebSessionsContext?, NoError> = .single(nil)
|
|
) -> Signal<[SettingsSearchableItem], NoError> {
|
|
let canAddAccount = activeAccountsAndPeers(context: context)
|
|
|> take(1)
|
|
|> map { accountsAndPeers -> Bool in
|
|
return accountsAndPeers.1.count + 1 < maximumNumberOfAccounts
|
|
}
|
|
|
|
let notificationSettings = context.account.postbox.preferencesView(keys: [PreferencesKeys.globalNotifications])
|
|
|> take(1)
|
|
|> map { view -> GlobalNotificationSettingsSet in
|
|
let viewSettings: GlobalNotificationSettingsSet
|
|
if let settings = view.values[PreferencesKeys.globalNotifications]?.get(GlobalNotificationSettings.self) {
|
|
viewSettings = settings.effective
|
|
} else {
|
|
viewSettings = GlobalNotificationSettingsSet.defaultSettings
|
|
}
|
|
return viewSettings
|
|
}
|
|
|
|
let archivedStickerPacks = archivedStickerPacks
|
|
|> take(1)
|
|
|
|
let privacySettings = privacySettings
|
|
|> take(1)
|
|
|
|
let proxyServers = context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.proxySettings])
|
|
|> map { sharedData -> ProxySettings in
|
|
if let value = sharedData.entries[SharedDataKeys.proxySettings]?.get(ProxySettings.self) {
|
|
return value
|
|
} else {
|
|
return ProxySettings.defaultSettings
|
|
}
|
|
}
|
|
|> map { settings -> [ProxyServerSettings] in
|
|
return settings.servers
|
|
}
|
|
|
|
let localizations = combineLatest(
|
|
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.LocalizationList()),
|
|
context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.localizationSettings])
|
|
)
|
|
|> map { localizationListState, sharedData -> [LocalizationInfo] in
|
|
if !localizationListState.availableOfficialLocalizations.isEmpty {
|
|
var existingIds = Set<String>()
|
|
let availableSavedLocalizations = localizationListState.availableSavedLocalizations.filter({ info in !localizationListState.availableOfficialLocalizations.contains(where: { $0.languageCode == info.languageCode }) })
|
|
|
|
var activeLanguageCode: String?
|
|
if let localizationSettings = sharedData.entries[SharedDataKeys.localizationSettings]?.get(LocalizationSettings.self) {
|
|
activeLanguageCode = localizationSettings.primaryComponent.languageCode
|
|
}
|
|
|
|
var localizationItems: [LocalizationInfo] = []
|
|
if !availableSavedLocalizations.isEmpty {
|
|
for info in availableSavedLocalizations {
|
|
if existingIds.contains(info.languageCode) || info.languageCode == activeLanguageCode {
|
|
continue
|
|
}
|
|
existingIds.insert(info.languageCode)
|
|
localizationItems.append(info)
|
|
}
|
|
}
|
|
for info in localizationListState.availableOfficialLocalizations {
|
|
if existingIds.contains(info.languageCode) || info.languageCode == activeLanguageCode {
|
|
continue
|
|
}
|
|
existingIds.insert(info.languageCode)
|
|
localizationItems.append(info)
|
|
}
|
|
|
|
return localizationItems
|
|
} else {
|
|
return []
|
|
}
|
|
}
|
|
|
|
let activeWebSessionsContext = webSessionsContext
|
|
|> mapToSignal { webSessionsContext -> Signal<WebSessionsContext?, NoError> in
|
|
if let webSessionsContext = webSessionsContext {
|
|
return webSessionsContext.state
|
|
|> map { state -> WebSessionsContext? in
|
|
if !state.sessions.isEmpty {
|
|
return webSessionsContext
|
|
} else {
|
|
return nil
|
|
}
|
|
}
|
|
|> distinctUntilChanged(isEqual: { lhs, rhs in
|
|
return lhs !== rhs
|
|
})
|
|
} else {
|
|
return .single(nil)
|
|
}
|
|
}
|
|
|
|
return combineLatest(
|
|
canAddAccount,
|
|
localizations,
|
|
notificationSettings,
|
|
notificationExceptionsList,
|
|
archivedStickerPacks,
|
|
proxyServers,
|
|
privacySettings,
|
|
hasTwoStepAuth,
|
|
twoStepAuthData,
|
|
activeSessionsContext,
|
|
activeWebSessionsContext
|
|
)
|
|
|> map {
|
|
canAddAccount,
|
|
localizations,
|
|
notificationSettings,
|
|
notificationExceptionsList,
|
|
archivedStickerPacks,
|
|
proxyServers,
|
|
privacySettings,
|
|
hasTwoStepAuth,
|
|
twoStepAuthData,
|
|
activeSessionsContext,
|
|
activeWebSessionsContext in
|
|
let strings = context.sharedContext.currentPresentationData.with { $0 }.strings
|
|
|
|
var allItems: [SettingsSearchableItem] = []
|
|
|
|
let profileItems = profileSearchableItems(context: context, canAddAccount: canAddAccount)
|
|
allItems.append(contentsOf: profileItems)
|
|
|
|
let savedMessages = SettingsSearchableItem(
|
|
id: "saved-messages",
|
|
title: strings.Settings_SavedMessages,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_SavedMessages),
|
|
icon: .savedMessages,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
present(.push, context.sharedContext.makeChatController(context: context, chatLocation: .peer(id: context.account.peerId), subject: nil, botStart: nil, mode: .standard(.default), params: nil))
|
|
}
|
|
)
|
|
allItems.append(savedMessages)
|
|
|
|
let devicesItems = devicesSearchableItems(context: context, activeSessionsContext: activeSessionsContext, webSessionsContext: activeWebSessionsContext)
|
|
allItems.append(contentsOf: devicesItems)
|
|
|
|
let callItems = callSearchableItems(context: context)
|
|
allItems.append(contentsOf: callItems)
|
|
|
|
let chatFolders = chatFoldersSearchableItems(context: context)
|
|
allItems.append(contentsOf: chatFolders)
|
|
|
|
let stickerItems = stickerSearchableItems(context: context, archivedStickerPacks: archivedStickerPacks)
|
|
allItems.append(contentsOf: stickerItems)
|
|
|
|
let notificationItems = notificationSearchableItems(context: context, settings: notificationSettings, exceptionsList: notificationExceptionsList)
|
|
allItems.append(contentsOf: notificationItems)
|
|
|
|
let privacyItems = privacySearchableItems(context: context, privacySettings: privacySettings, activeSessionsContext: activeSessionsContext, webSessionsContext: activeWebSessionsContext)
|
|
allItems.append(contentsOf: privacyItems)
|
|
|
|
let dataItems = dataSearchableItems(context: context)
|
|
allItems.append(contentsOf: dataItems)
|
|
|
|
let proxyItems = proxySearchableItems(context: context, servers: proxyServers)
|
|
allItems.append(contentsOf: proxyItems)
|
|
|
|
let appearanceItems = appearanceSearchableItems(context: context)
|
|
allItems.append(contentsOf: appearanceItems)
|
|
|
|
let powerSavingItems = energySavingSearchableItems(context: context)
|
|
allItems.append(contentsOf: powerSavingItems)
|
|
|
|
let languageItems = languageSearchableItems(context: context, localizations: localizations)
|
|
allItems.append(contentsOf: languageItems)
|
|
|
|
let premiumItems = premiumSearchableItems(context: context)
|
|
allItems.append(contentsOf: premiumItems)
|
|
|
|
let storiesItems = myProfileSearchableItems(context: context)
|
|
allItems.append(contentsOf: storiesItems)
|
|
|
|
if let hasTwoStepAuth = hasTwoStepAuth,
|
|
hasTwoStepAuth {
|
|
let passport = SettingsSearchableItem(
|
|
id: "passport",
|
|
title: strings.Settings_Passport,
|
|
alternate: synonyms(strings.SettingsSearch_Synonyms_Passport),
|
|
icon: .passport,
|
|
breadcrumbs: [],
|
|
present: { context, _, present in
|
|
present(.modal, SecureIdAuthController(context: context, mode: .list))
|
|
}
|
|
)
|
|
allItems.append(passport)
|
|
}
|
|
|
|
let helpItems = helpSearchableItems(context: context)
|
|
allItems.append(contentsOf: helpItems)
|
|
|
|
let deleteAccount = SettingsSearchableItem(
|
|
id: "delete-account",
|
|
title: strings.DeleteAccount_DeleteMyAccount,
|
|
alternate: synonyms(strings.SettingsSearch_DeleteAccount_DeleteMyAccount),
|
|
icon: .deleteAccount,
|
|
breadcrumbs: [],
|
|
present: { context, navigationController, present in
|
|
if let navigationController = navigationController {
|
|
let controller = deleteAccountOptionsController(context: context, navigationController: navigationController, hasTwoStepAuth: hasTwoStepAuth ?? false, twoStepAuthData: twoStepAuthData)
|
|
present(.push, controller)
|
|
}
|
|
}
|
|
)
|
|
allItems.append(deleteAccount)
|
|
|
|
return allItems
|
|
}
|
|
}
|
|
|
|
private func stringTokens(_ string: String) -> [ValueBoxKey] {
|
|
let nsString = string.folding(options: .diacriticInsensitive, locale: .current).lowercased() as NSString
|
|
|
|
let flag = UInt(kCFStringTokenizerUnitWord)
|
|
let tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, nsString, CFRangeMake(0, nsString.length), flag, CFLocaleCopyCurrent())
|
|
var tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)
|
|
var tokens: [ValueBoxKey] = []
|
|
|
|
var addedTokens = Set<ValueBoxKey>()
|
|
while tokenType != [] {
|
|
let currentTokenRange = CFStringTokenizerGetCurrentTokenRange(tokenizer)
|
|
|
|
if currentTokenRange.location >= 0 && currentTokenRange.length != 0 {
|
|
let token = ValueBoxKey(length: currentTokenRange.length * 2)
|
|
nsString.getCharacters(token.memory.assumingMemoryBound(to: unichar.self), range: NSMakeRange(currentTokenRange.location, currentTokenRange.length))
|
|
if !addedTokens.contains(token) {
|
|
tokens.append(token)
|
|
addedTokens.insert(token)
|
|
}
|
|
}
|
|
tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)
|
|
}
|
|
|
|
return tokens
|
|
}
|
|
|
|
private func matchStringTokens(_ tokens: [ValueBoxKey], with other: [ValueBoxKey]) -> Bool {
|
|
if other.isEmpty {
|
|
return false
|
|
} else if other.count == 1 {
|
|
let otherToken = other[0]
|
|
for token in tokens {
|
|
if otherToken.isPrefix(to: token) {
|
|
return true
|
|
}
|
|
}
|
|
} else {
|
|
for otherToken in other {
|
|
var found = false
|
|
for token in tokens {
|
|
if otherToken.isPrefix(to: token) {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func searchSettingsItems(items: [SettingsSearchableItem], query: String) -> [SettingsSearchableItem] {
|
|
let showAll = query == "#all"
|
|
|
|
let queryTokens = stringTokens(query.lowercased())
|
|
|
|
var result: [SettingsSearchableItem] = []
|
|
for item in items {
|
|
guard item.isVisible || showAll else {
|
|
continue
|
|
}
|
|
var string = item.title
|
|
if !item.alternate.isEmpty {
|
|
for alternate in item.alternate {
|
|
let trimmed = alternate.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
if !trimmed.isEmpty {
|
|
string += " \(trimmed)"
|
|
}
|
|
}
|
|
}
|
|
if item.breadcrumbs.count > 1 {
|
|
string += " \(item.breadcrumbs.suffix(from: 1).joined(separator: " "))"
|
|
}
|
|
|
|
let tokens = stringTokens(string)
|
|
if showAll || matchStringTokens(tokens, with: queryTokens) {
|
|
var item = item
|
|
if item.title.isEmpty && !item.isVisible, let id = item.id.base as? String {
|
|
item = item.withUpdatedTitle(id)
|
|
}
|
|
result.append(item)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
public func handleSettingsPathUrl(context: AccountContext, path: String, navigationController: NavigationController) {
|
|
let _ = (settingsSearchableItems(context: context)
|
|
|> take(1)
|
|
|> deliverOnMainQueue).start(next: { items in
|
|
guard let item = items.first(where: { $0.id == AnyHashable(path) }) else {
|
|
return
|
|
}
|
|
item.present(context, navigationController, { mode, controller in
|
|
guard let controller, let topController = navigationController.topViewController as? ViewController else {
|
|
return
|
|
}
|
|
switch mode {
|
|
case .push:
|
|
navigationController.pushViewController(controller)
|
|
case .modal:
|
|
topController.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet, completion: {}), blockInteraction: false, completion: {})
|
|
case .immediate:
|
|
topController.present(controller, in: .window(.root))
|
|
default:
|
|
break
|
|
}
|
|
})
|
|
})
|
|
}
|
|
|
|
private func presentSetupBirthday(context: AccountContext, present: @escaping (SettingsSearchableItemPresentation, ViewController?) -> Void) {
|
|
let settingsPromise: Promise<AccountPrivacySettings?>
|
|
if let rootController = context.sharedContext.mainWindow?.viewController as? TelegramRootControllerInterface, let current = rootController.getPrivacySettings() {
|
|
settingsPromise = current
|
|
} else {
|
|
settingsPromise = Promise()
|
|
settingsPromise.set(.single(nil) |> then(context.engine.privacy.requestAccountPrivacySettings() |> map(Optional.init)))
|
|
}
|
|
|
|
let controller = context.sharedContext.makeBirthdayPickerScreen(
|
|
context: context,
|
|
settings: settingsPromise,
|
|
openSettings: {
|
|
context.sharedContext.makeBirthdayPrivacyController(context: context, settings: settingsPromise, openedFromBirthdayScreen: true, present: { c in
|
|
present(.push, c)
|
|
})
|
|
},
|
|
completion: { value in
|
|
let _ = context.engine.accountData.updateBirthday(birthday: value).startStandalone()
|
|
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
present(.immediate, UndoOverlayController(presentationData: presentationData, content: .actionSucceeded(title: nil, text: presentationData.strings.Birthday_Added, cancel: nil, destructive: false), elevatedLayout: false, action: { _ in
|
|
return true
|
|
}))
|
|
}
|
|
)
|
|
present(.push, controller)
|
|
}
|