mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 11:23:48 +00:00
722 lines
46 KiB
Swift
722 lines
46 KiB
Swift
// MARK: Swiftgram
|
|
import SGLogging
|
|
import SGSimpleSettings
|
|
import SGStrings
|
|
import SGAPIToken
|
|
|
|
import SGItemListUI
|
|
import Foundation
|
|
import UIKit
|
|
import Display
|
|
import SwiftSignalKit
|
|
import Postbox
|
|
import TelegramCore
|
|
import MtProtoKit
|
|
import MessageUI
|
|
import TelegramPresentationData
|
|
import TelegramUIPreferences
|
|
import ItemListUI
|
|
import PresentationDataUtils
|
|
import OverlayStatusController
|
|
import AccountContext
|
|
import AppBundle
|
|
import WebKit
|
|
import PeerNameColorScreen
|
|
import UndoUI
|
|
|
|
|
|
private enum SGControllerSection: Int32, SGItemListSection {
|
|
case search
|
|
case content
|
|
case tabs
|
|
case folders
|
|
case chatList
|
|
case profiles
|
|
case stories
|
|
case translation
|
|
case voiceMessages
|
|
case photo
|
|
case stickers
|
|
case videoNotes
|
|
case contextMenu
|
|
case accountColors
|
|
case other
|
|
}
|
|
|
|
private enum SGBoolSetting: String {
|
|
case hidePhoneInSettings
|
|
case showTabNames
|
|
case showContactsTab
|
|
case showCallsTab
|
|
case foldersAtBottom
|
|
case startTelescopeWithRearCam
|
|
case hideStories
|
|
case uploadSpeedBoost
|
|
case showProfileId
|
|
case warnOnStoriesOpen
|
|
case sendWithReturnKey
|
|
case rememberLastFolder
|
|
case sendLargePhotos
|
|
case storyStealthMode
|
|
case disableSwipeToRecordStory
|
|
case disableDeleteChatSwipeOption
|
|
case quickTranslateButton
|
|
case hideReactions
|
|
case showRepostToStory
|
|
case contextShowSelectFromUser
|
|
case contextShowSaveToCloud
|
|
case contextShowHideForwardName
|
|
case contextShowRestrict
|
|
case contextShowReport
|
|
case contextShowReply
|
|
case contextShowPin
|
|
case contextShowSaveMedia
|
|
case contextShowMessageReplies
|
|
case contextShowJson
|
|
case disableScrollToNextChannel
|
|
case disableScrollToNextTopic
|
|
case disableChatSwipeOptions
|
|
case disableGalleryCamera
|
|
case disableGalleryCameraPreview
|
|
case disableSendAsButton
|
|
case disableSnapDeletionEffect
|
|
case stickerTimestamp
|
|
case hideRecordingButton
|
|
case hideTabBar
|
|
case showDC
|
|
case showCreationDate
|
|
case showRegDate
|
|
case compactChatList
|
|
case compactFolderNames
|
|
case allChatsHidden
|
|
case defaultEmojisFirst
|
|
case messageDoubleTapActionOutgoingEdit
|
|
case wideChannelPosts
|
|
case forceEmojiTab
|
|
case forceBuiltInMic
|
|
case secondsInMessages
|
|
case hideChannelBottomButton
|
|
case confirmCalls
|
|
case swipeForVideoPIP
|
|
}
|
|
|
|
private enum SGOneFromManySetting: String {
|
|
case bottomTabStyle
|
|
case downloadSpeedBoost
|
|
case allChatsTitleLengthOverride
|
|
// case allChatsFolderPositionOverride
|
|
case translationBackend
|
|
case transcriptionBackend
|
|
}
|
|
|
|
private enum SGSliderSetting: String {
|
|
case accountColorsSaturation
|
|
case outgoingPhotoQuality
|
|
case stickerSize
|
|
}
|
|
|
|
private enum SGDisclosureLink: String {
|
|
case contentSettings
|
|
case languageSettings
|
|
}
|
|
|
|
private struct PeerNameColorScreenState: Equatable {
|
|
var updatedNameColor: PeerNameColor?
|
|
var updatedBackgroundEmojiId: Int64?
|
|
}
|
|
|
|
private struct SGSettingsControllerState: Equatable {
|
|
var searchQuery: String?
|
|
}
|
|
|
|
private typealias SGControllerEntry = SGItemListUIEntry<SGControllerSection, SGBoolSetting, SGSliderSetting, SGOneFromManySetting, SGDisclosureLink, AnyHashable>
|
|
|
|
private func SGControllerEntries(presentationData: PresentationData, callListSettings: CallListSettings, experimentalUISettings: ExperimentalUISettings, SGSettings: SGUISettings, appConfiguration: AppConfiguration, nameColors: PeerNameColors, state: SGSettingsControllerState) -> [SGControllerEntry] {
|
|
|
|
let lang = presentationData.strings.baseLanguageCode
|
|
var entries: [SGControllerEntry] = []
|
|
|
|
let id = SGItemListCounter()
|
|
|
|
entries.append(.searchInput(id: id.count, section: .search, title: NSAttributedString(string: "🔍"), text: state.searchQuery ?? "", placeholder: presentationData.strings.Common_Search))
|
|
if appConfiguration.sgWebSettings.global.canEditSettings {
|
|
entries.append(.disclosure(id: id.count, section: .content, link: .contentSettings, text: i18n("Settings.ContentSettings", lang)))
|
|
} else {
|
|
id.increment(1)
|
|
}
|
|
|
|
entries.append(.header(id: id.count, section: .tabs, text: i18n("Settings.Tabs.Header", lang), badge: nil))
|
|
entries.append(.toggle(id: id.count, section: .tabs, settingName: .hideTabBar, value: SGSimpleSettings.shared.hideTabBar, text: i18n("Settings.Tabs.HideTabBar", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .tabs, settingName: .showContactsTab, value: callListSettings.showContactsTab, text: i18n("Settings.Tabs.ShowContacts", lang), enabled: !SGSimpleSettings.shared.hideTabBar))
|
|
entries.append(.toggle(id: id.count, section: .tabs, settingName: .showCallsTab, value: callListSettings.showTab, text: presentationData.strings.CallSettings_TabIcon, enabled: !SGSimpleSettings.shared.hideTabBar))
|
|
entries.append(.toggle(id: id.count, section: .tabs, settingName: .showTabNames, value: SGSimpleSettings.shared.showTabNames, text: i18n("Settings.Tabs.ShowNames", lang), enabled: !SGSimpleSettings.shared.hideTabBar))
|
|
|
|
entries.append(.header(id: id.count, section: .folders, text: presentationData.strings.Settings_ChatFolders.uppercased(), badge: nil))
|
|
entries.append(.toggle(id: id.count, section: .folders, settingName: .foldersAtBottom, value: experimentalUISettings.foldersTabAtBottom, text: i18n("Settings.Folders.BottomTab", lang), enabled: true))
|
|
entries.append(.oneFromManySelector(id: id.count, section: .folders, settingName: .bottomTabStyle, text: i18n("Settings.Folders.BottomTabStyle", lang), value: i18n("Settings.Folders.BottomTabStyle.\(SGSimpleSettings.shared.bottomTabStyle)", lang), enabled: experimentalUISettings.foldersTabAtBottom))
|
|
entries.append(.toggle(id: id.count, section: .folders, settingName: .allChatsHidden, value: SGSimpleSettings.shared.allChatsHidden, text: i18n("Settings.Folders.AllChatsHidden", lang, presentationData.strings.ChatList_Tabs_AllChats), enabled: true))
|
|
#if DEBUG
|
|
// entries.append(.oneFromManySelector(id: id.count, section: .folders, settingName: .allChatsFolderPositionOverride, text: i18n("Settings.Folders.AllChatsPlacement", lang), value: i18n("Settings.Folders.AllChatsPlacement.\(SGSimpleSettings.shared.allChatsFolderPositionOverride)", lang), enabled: true))
|
|
#endif
|
|
entries.append(.toggle(id: id.count, section: .folders, settingName: .compactFolderNames, value: SGSimpleSettings.shared.compactFolderNames, text: i18n("Settings.Folders.CompactNames", lang), enabled: SGSimpleSettings.shared.bottomTabStyle != SGSimpleSettings.BottomTabStyleValues.ios.rawValue))
|
|
entries.append(.oneFromManySelector(id: id.count, section: .folders, settingName: .allChatsTitleLengthOverride, text: i18n("Settings.Folders.AllChatsTitle", lang), value: i18n("Settings.Folders.AllChatsTitle.\(SGSimpleSettings.shared.allChatsTitleLengthOverride)", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .folders, settingName: .rememberLastFolder, value: SGSimpleSettings.shared.rememberLastFolder, text: i18n("Settings.Folders.RememberLast", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .folders, text: i18n("Settings.Folders.RememberLast.Notice", lang)))
|
|
|
|
entries.append(.header(id: id.count, section: .chatList, text: i18n("Settings.ChatList.Header", lang), badge: nil))
|
|
entries.append(.toggle(id: id.count, section: .chatList, settingName: .compactChatList, value: SGSimpleSettings.shared.compactChatList, text: i18n("Settings.CompactChatList", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .chatList, settingName: .disableChatSwipeOptions, value: !SGSimpleSettings.shared.disableChatSwipeOptions, text: i18n("Settings.ChatSwipeOptions", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .chatList, settingName: .disableDeleteChatSwipeOption, value: !SGSimpleSettings.shared.disableDeleteChatSwipeOption, text: i18n("Settings.DeleteChatSwipeOption", lang), enabled: !SGSimpleSettings.shared.disableChatSwipeOptions))
|
|
|
|
entries.append(.header(id: id.count, section: .profiles, text: i18n("Settings.Profiles.Header", lang), badge: nil))
|
|
entries.append(.toggle(id: id.count, section: .profiles, settingName: .showProfileId, value: SGSettings.showProfileId, text: i18n("Settings.ShowProfileID", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .profiles, settingName: .showDC, value: SGSimpleSettings.shared.showDC, text: i18n("Settings.ShowDC", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .profiles, settingName: .showRegDate, value: SGSimpleSettings.shared.showRegDate, text: i18n("Settings.ShowRegDate", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .profiles, text: i18n("Settings.ShowRegDate.Notice", lang)))
|
|
entries.append(.toggle(id: id.count, section: .profiles, settingName: .showCreationDate, value: SGSimpleSettings.shared.showCreationDate, text: i18n("Settings.ShowCreationDate", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .profiles, text: i18n("Settings.ShowCreationDate.Notice", lang)))
|
|
entries.append(.toggle(id: id.count, section: .profiles, settingName: .confirmCalls, value: SGSimpleSettings.shared.confirmCalls, text: i18n("Settings.CallConfirmation", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .profiles, text: i18n("Settings.CallConfirmation.Notice", lang)))
|
|
|
|
entries.append(.header(id: id.count, section: .stories, text: presentationData.strings.AutoDownloadSettings_Stories.uppercased(), badge: nil))
|
|
entries.append(.toggle(id: id.count, section: .stories, settingName: .hideStories, value: SGSettings.hideStories, text: i18n("Settings.Stories.Hide", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .stories, settingName: .disableSwipeToRecordStory, value: SGSimpleSettings.shared.disableSwipeToRecordStory, text: i18n("Settings.Stories.DisableSwipeToRecord", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .stories, settingName: .warnOnStoriesOpen, value: SGSettings.warnOnStoriesOpen, text: i18n("Settings.Stories.WarnBeforeView", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .stories, settingName: .showRepostToStory, value: SGSimpleSettings.shared.showRepostToStory, text: presentationData.strings.Share_RepostToStory.replacingOccurrences(of: "\n", with: " "), enabled: true))
|
|
if SGSimpleSettings.shared.canUseStealthMode {
|
|
entries.append(.toggle(id: id.count, section: .stories, settingName: .storyStealthMode, value: SGSimpleSettings.shared.storyStealthMode, text: presentationData.strings.Story_StealthMode_Title, enabled: true))
|
|
entries.append(.notice(id: id.count, section: .stories, text: presentationData.strings.Story_StealthMode_ControlText))
|
|
} else {
|
|
id.increment(2)
|
|
}
|
|
|
|
|
|
entries.append(.header(id: id.count, section: .translation, text: presentationData.strings.Localization_TranslateMessages.uppercased(), badge: nil))
|
|
entries.append(.oneFromManySelector(id: id.count, section: .translation, settingName: .translationBackend, text: i18n("Settings.Translation.Backend", lang), value: i18n("Settings.Translation.Backend.\(SGSimpleSettings.shared.translationBackend)", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .translation, text: i18n("Settings.Translation.Backend.Notice", lang)))
|
|
entries.append(.toggle(id: id.count, section: .translation, settingName: .quickTranslateButton, value: SGSimpleSettings.shared.quickTranslateButton, text: i18n("Settings.Translation.QuickTranslateButton", lang), enabled: true))
|
|
entries.append(.disclosure(id: id.count, section: .translation, link: .languageSettings, text: presentationData.strings.Localization_TranslateEntireChat))
|
|
entries.append(.notice(id: id.count, section: .translation, text: i18n("Common.NoTelegramPremiumNeeded", lang, presentationData.strings.Settings_Premium)))
|
|
|
|
entries.append(.header(id: id.count, section: .voiceMessages, text: "Settings.Transcription.Header".i18n(lang), badge: nil))
|
|
entries.append(.oneFromManySelector(id: id.count, section: .voiceMessages, settingName: .transcriptionBackend, text: i18n("Settings.Transcription.Backend", lang), value: i18n("Settings.Transcription.Backend.\(SGSimpleSettings.shared.transcriptionBackend)", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .voiceMessages, text: i18n("Settings.Transcription.Backend.Notice", lang)))
|
|
entries.append(.header(id: id.count, section: .voiceMessages, text: presentationData.strings.Privacy_VoiceMessages.uppercased(), badge: nil))
|
|
entries.append(.toggle(id: id.count, section: .voiceMessages, settingName: .forceBuiltInMic, value: SGSimpleSettings.shared.forceBuiltInMic, text: i18n("Settings.forceBuiltInMic", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .voiceMessages, text: i18n("Settings.forceBuiltInMic.Notice", lang)))
|
|
|
|
entries.append(.header(id: id.count, section: .photo, text: presentationData.strings.NetworkUsageSettings_MediaImageDataSection, badge: nil))
|
|
entries.append(.header(id: id.count, section: .photo, text: presentationData.strings.PhotoEditor_QualityTool.uppercased(), badge: nil))
|
|
entries.append(.percentageSlider(id: id.count, section: .photo, settingName: .outgoingPhotoQuality, value: SGSimpleSettings.shared.outgoingPhotoQuality))
|
|
entries.append(.notice(id: id.count, section: .photo, text: i18n("Settings.Photo.Quality.Notice", lang)))
|
|
entries.append(.toggle(id: id.count, section: .photo, settingName: .sendLargePhotos, value: SGSimpleSettings.shared.sendLargePhotos, text: i18n("Settings.Photo.SendLarge", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .photo, text: i18n("Settings.Photo.SendLarge.Notice", lang)))
|
|
|
|
entries.append(.header(id: id.count, section: .stickers, text: presentationData.strings.StickerPacksSettings_Title.uppercased(), badge: nil))
|
|
entries.append(.header(id: id.count, section: .stickers, text: i18n("Settings.Stickers.Size", lang), badge: nil))
|
|
entries.append(.percentageSlider(id: id.count, section: .stickers, settingName: .stickerSize, value: SGSimpleSettings.shared.stickerSize))
|
|
entries.append(.toggle(id: id.count, section: .stickers, settingName: .stickerTimestamp, value: SGSimpleSettings.shared.stickerTimestamp, text: i18n("Settings.Stickers.Timestamp", lang), enabled: true))
|
|
|
|
|
|
entries.append(.header(id: id.count, section: .videoNotes, text: i18n("Settings.VideoNotes.Header", lang), badge: nil))
|
|
entries.append(.toggle(id: id.count, section: .videoNotes, settingName: .startTelescopeWithRearCam, value: SGSimpleSettings.shared.startTelescopeWithRearCam, text: i18n("Settings.VideoNotes.StartWithRearCam", lang), enabled: true))
|
|
|
|
entries.append(.header(id: id.count, section: .contextMenu, text: i18n("Settings.ContextMenu", lang), badge: nil))
|
|
entries.append(.notice(id: id.count, section: .contextMenu, text: i18n("Settings.ContextMenu.Notice", lang)))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowSaveToCloud, value: SGSimpleSettings.shared.contextShowSaveToCloud, text: i18n("ContextMenu.SaveToCloud", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowHideForwardName, value: SGSimpleSettings.shared.contextShowHideForwardName, text: presentationData.strings.Conversation_ForwardOptions_HideSendersNames, enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowSelectFromUser, value: SGSimpleSettings.shared.contextShowSelectFromUser, text: i18n("ContextMenu.SelectFromUser", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowRestrict, value: SGSimpleSettings.shared.contextShowRestrict, text: presentationData.strings.Conversation_ContextMenuBan, enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowReport, value: SGSimpleSettings.shared.contextShowReport, text: presentationData.strings.Conversation_ContextMenuReport, enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowReply, value: SGSimpleSettings.shared.contextShowReply, text: presentationData.strings.Conversation_ContextMenuReply, enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowPin, value: SGSimpleSettings.shared.contextShowPin, text: presentationData.strings.Conversation_Pin, enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowSaveMedia, value: SGSimpleSettings.shared.contextShowSaveMedia, text: presentationData.strings.Conversation_SaveToFiles, enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowMessageReplies, value: SGSimpleSettings.shared.contextShowMessageReplies, text: presentationData.strings.Conversation_ContextViewThread, enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowJson, value: SGSimpleSettings.shared.contextShowJson, text: "JSON", enabled: true))
|
|
/* entries.append(.toggle(id: id.count, section: .contextMenu, settingName: .contextShowRestrict, value: SGSimpleSettings.shared.contextShowRestrict, text: presentationData.strings.Conversation_ContextMenuBan)) */
|
|
|
|
entries.append(.header(id: id.count, section: .accountColors, text: i18n("Settings.CustomColors.Header", lang), badge: nil))
|
|
entries.append(.header(id: id.count, section: .accountColors, text: i18n("Settings.CustomColors.Saturation", lang), badge: nil))
|
|
let accountColorSaturation = SGSimpleSettings.shared.accountColorsSaturation
|
|
entries.append(.percentageSlider(id: id.count, section: .accountColors, settingName: .accountColorsSaturation, value: accountColorSaturation))
|
|
// let nameColor: PeerNameColor
|
|
// if let updatedNameColor = state.updatedNameColor {
|
|
// nameColor = updatedNameColor
|
|
// } else {
|
|
// nameColor = .blue
|
|
// }
|
|
// let _ = nameColors.get(nameColor, dark: presentationData.theme.overallDarkAppearance)
|
|
// entries.append(.peerColorPicker(id: entries.count, section: .other,
|
|
// colors: nameColors,
|
|
// currentColor: nameColor, // TODO: PeerNameColor(rawValue: <#T##Int32#>)
|
|
// currentSaturation: accountColorSaturation
|
|
// ))
|
|
|
|
if accountColorSaturation == 0 {
|
|
id.increment(100)
|
|
entries.append(.peerColorDisclosurePreview(id: id.count, section: .accountColors, name: "\(presentationData.strings.UserInfo_FirstNamePlaceholder) \(presentationData.strings.UserInfo_LastNamePlaceholder)", color: presentationData.theme.chat.message.incoming.accentTextColor))
|
|
} else {
|
|
id.increment(200)
|
|
for index in nameColors.displayOrder.prefix(3) {
|
|
let color: PeerNameColor = PeerNameColor(rawValue: index)
|
|
let colors = nameColors.get(color, dark: presentationData.theme.overallDarkAppearance)
|
|
entries.append(.peerColorDisclosurePreview(id: id.count, section: .accountColors, name: "\(presentationData.strings.UserInfo_FirstNamePlaceholder) \(presentationData.strings.UserInfo_LastNamePlaceholder)", color: colors.main))
|
|
}
|
|
}
|
|
entries.append(.notice(id: id.count, section: .accountColors, text: i18n("Settings.CustomColors.Saturation.Notice", lang)))
|
|
|
|
id.increment(10000)
|
|
entries.append(.header(id: id.count, section: .other, text: presentationData.strings.Appearance_Other.uppercased(), badge: nil))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .swipeForVideoPIP, value: SGSimpleSettings.shared.videoPIPSwipeDirection == SGSimpleSettings.VideoPIPSwipeDirection.up.rawValue, text: i18n("Settings.swipeForVideoPIP", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .other, text: i18n("Settings.swipeForVideoPIP.Notice", lang)))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .hideChannelBottomButton, value: !SGSimpleSettings.shared.hideChannelBottomButton, text: i18n("Settings.showChannelBottomButton", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .wideChannelPosts, value: SGSimpleSettings.shared.wideChannelPosts, text: i18n("Settings.wideChannelPosts", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .secondsInMessages, value: SGSimpleSettings.shared.secondsInMessages, text: i18n("Settings.secondsInMessages", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .messageDoubleTapActionOutgoingEdit, value: SGSimpleSettings.shared.messageDoubleTapActionOutgoing == SGSimpleSettings.MessageDoubleTapAction.edit.rawValue, text: i18n("Settings.messageDoubleTapActionOutgoingEdit", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .hideRecordingButton, value: !SGSimpleSettings.shared.hideRecordingButton, text: i18n("Settings.RecordingButton", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .disableSnapDeletionEffect, value: !SGSimpleSettings.shared.disableSnapDeletionEffect, text: i18n("Settings.SnapDeletionEffect", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .disableSendAsButton, value: !SGSimpleSettings.shared.disableSendAsButton, text: i18n("Settings.SendAsButton", lang, presentationData.strings.Conversation_SendMesageAs), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .disableGalleryCamera, value: !SGSimpleSettings.shared.disableGalleryCamera, text: i18n("Settings.GalleryCamera", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .disableGalleryCameraPreview, value: !SGSimpleSettings.shared.disableGalleryCameraPreview, text: i18n("Settings.GalleryCameraPreview", lang), enabled: !SGSimpleSettings.shared.disableGalleryCamera))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .disableScrollToNextChannel, value: !SGSimpleSettings.shared.disableScrollToNextChannel, text: i18n("Settings.PullToNextChannel", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .disableScrollToNextTopic, value: !SGSimpleSettings.shared.disableScrollToNextTopic, text: i18n("Settings.PullToNextTopic", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .hideReactions, value: SGSimpleSettings.shared.hideReactions, text: i18n("Settings.HideReactions", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .uploadSpeedBoost, value: SGSimpleSettings.shared.uploadSpeedBoost, text: i18n("Settings.UploadsBoost", lang), enabled: true))
|
|
entries.append(.oneFromManySelector(id: id.count, section: .other, settingName: .downloadSpeedBoost, text: i18n("Settings.DownloadsBoost", lang), value: i18n("Settings.DownloadsBoost.\(SGSimpleSettings.shared.downloadSpeedBoost)", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .other, text: i18n("Settings.DownloadsBoost.Notice", lang)))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .sendWithReturnKey, value: SGSettings.sendWithReturnKey, text: i18n("Settings.SendWithReturnKey", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .forceEmojiTab, value: SGSimpleSettings.shared.forceEmojiTab, text: i18n("Settings.ForceEmojiTab", lang), enabled: true))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .defaultEmojisFirst, value: SGSimpleSettings.shared.defaultEmojisFirst, text: i18n("Settings.DefaultEmojisFirst", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .other, text: i18n("Settings.DefaultEmojisFirst.Notice", lang)))
|
|
entries.append(.toggle(id: id.count, section: .other, settingName: .hidePhoneInSettings, value: SGSimpleSettings.shared.hidePhoneInSettings, text: i18n("Settings.HidePhoneInSettingsUI", lang), enabled: true))
|
|
entries.append(.notice(id: id.count, section: .other, text: i18n("Settings.HidePhoneInSettingsUI.Notice", lang)))
|
|
|
|
return filterSGItemListUIEntrires(entries: entries, by: state.searchQuery)
|
|
}
|
|
|
|
public func sgSettingsController(context: AccountContext/*, focusOnItemTag: Int? = nil*/) -> ViewController {
|
|
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
|
|
var pushControllerImpl: ((ViewController) -> Void)?
|
|
// var getRootControllerImpl: (() -> UIViewController?)?
|
|
// var getNavigationControllerImpl: (() -> NavigationController?)?
|
|
var askForRestart: (() -> Void)?
|
|
|
|
let initialState = SGSettingsControllerState()
|
|
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
|
let stateValue = Atomic(value: initialState)
|
|
let updateState: ((SGSettingsControllerState) -> SGSettingsControllerState) -> Void = { f in
|
|
statePromise.set(stateValue.modify { f($0) })
|
|
}
|
|
|
|
// let sliderPromise = ValuePromise(SGSimpleSettings.shared.accountColorsSaturation, ignoreRepeated: true)
|
|
// let sliderStateValue = Atomic(value: SGSimpleSettings.shared.accountColorsSaturation)
|
|
// let _: ((Int32) -> Int32) -> Void = { f in
|
|
// sliderPromise.set(sliderStateValue.modify( {f($0)}))
|
|
// }
|
|
|
|
let simplePromise = ValuePromise(true, ignoreRepeated: false)
|
|
|
|
let arguments = SGItemListArguments<SGBoolSetting, SGSliderSetting, SGOneFromManySetting, SGDisclosureLink, AnyHashable>(
|
|
context: context,
|
|
/*updatePeerColor: { color in
|
|
updateState { state in
|
|
var updatedState = state
|
|
updatedState.updatedNameColor = color
|
|
return updatedState
|
|
}
|
|
},*/ setBoolValue: { setting, value in
|
|
switch setting {
|
|
case .hidePhoneInSettings:
|
|
SGSimpleSettings.shared.hidePhoneInSettings = value
|
|
askForRestart?()
|
|
case .showTabNames:
|
|
SGSimpleSettings.shared.showTabNames = value
|
|
askForRestart?()
|
|
case .showContactsTab:
|
|
let _ = (
|
|
updateCallListSettingsInteractively(
|
|
accountManager: context.sharedContext.accountManager, { $0.withUpdatedShowContactsTab(value) }
|
|
)
|
|
).start()
|
|
case .showCallsTab:
|
|
let _ = (
|
|
updateCallListSettingsInteractively(
|
|
accountManager: context.sharedContext.accountManager, { $0.withUpdatedShowTab(value) }
|
|
)
|
|
).start()
|
|
case .foldersAtBottom:
|
|
let _ = (
|
|
updateExperimentalUISettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
|
var settings = settings
|
|
settings.foldersTabAtBottom = value
|
|
return settings
|
|
}
|
|
)
|
|
).start()
|
|
case .startTelescopeWithRearCam:
|
|
SGSimpleSettings.shared.startTelescopeWithRearCam = value
|
|
case .hideStories:
|
|
let _ = (
|
|
updateSGUISettings(engine: context.engine, { settings in
|
|
var settings = settings
|
|
settings.hideStories = value
|
|
return settings
|
|
})
|
|
).start()
|
|
case .showProfileId:
|
|
let _ = (
|
|
updateSGUISettings(engine: context.engine, { settings in
|
|
var settings = settings
|
|
settings.showProfileId = value
|
|
return settings
|
|
})
|
|
).start()
|
|
case .warnOnStoriesOpen:
|
|
let _ = (
|
|
updateSGUISettings(engine: context.engine, { settings in
|
|
var settings = settings
|
|
settings.warnOnStoriesOpen = value
|
|
return settings
|
|
})
|
|
).start()
|
|
case .sendWithReturnKey:
|
|
let _ = (
|
|
updateSGUISettings(engine: context.engine, { settings in
|
|
var settings = settings
|
|
settings.sendWithReturnKey = value
|
|
return settings
|
|
})
|
|
).start()
|
|
case .rememberLastFolder:
|
|
SGSimpleSettings.shared.rememberLastFolder = value
|
|
case .sendLargePhotos:
|
|
SGSimpleSettings.shared.sendLargePhotos = value
|
|
case .storyStealthMode:
|
|
SGSimpleSettings.shared.storyStealthMode = value
|
|
case .disableSwipeToRecordStory:
|
|
SGSimpleSettings.shared.disableSwipeToRecordStory = value
|
|
case .quickTranslateButton:
|
|
SGSimpleSettings.shared.quickTranslateButton = value
|
|
case .uploadSpeedBoost:
|
|
SGSimpleSettings.shared.uploadSpeedBoost = value
|
|
case .hideReactions:
|
|
SGSimpleSettings.shared.hideReactions = value
|
|
case .showRepostToStory:
|
|
SGSimpleSettings.shared.showRepostToStory = value
|
|
case .contextShowSelectFromUser:
|
|
SGSimpleSettings.shared.contextShowSelectFromUser = value
|
|
case .contextShowSaveToCloud:
|
|
SGSimpleSettings.shared.contextShowSaveToCloud = value
|
|
case .contextShowRestrict:
|
|
SGSimpleSettings.shared.contextShowRestrict = value
|
|
case .contextShowHideForwardName:
|
|
SGSimpleSettings.shared.contextShowHideForwardName = value
|
|
case .disableScrollToNextChannel:
|
|
SGSimpleSettings.shared.disableScrollToNextChannel = !value
|
|
case .disableScrollToNextTopic:
|
|
SGSimpleSettings.shared.disableScrollToNextTopic = !value
|
|
case .disableChatSwipeOptions:
|
|
SGSimpleSettings.shared.disableChatSwipeOptions = !value
|
|
simplePromise.set(true) // Trigger update for 'enabled' field of other toggles
|
|
askForRestart?()
|
|
case .disableDeleteChatSwipeOption:
|
|
SGSimpleSettings.shared.disableDeleteChatSwipeOption = !value
|
|
askForRestart?()
|
|
case .disableGalleryCamera:
|
|
SGSimpleSettings.shared.disableGalleryCamera = !value
|
|
simplePromise.set(true)
|
|
case .disableGalleryCameraPreview:
|
|
SGSimpleSettings.shared.disableGalleryCameraPreview = !value
|
|
case .disableSendAsButton:
|
|
SGSimpleSettings.shared.disableSendAsButton = !value
|
|
case .disableSnapDeletionEffect:
|
|
SGSimpleSettings.shared.disableSnapDeletionEffect = !value
|
|
case .contextShowReport:
|
|
SGSimpleSettings.shared.contextShowReport = value
|
|
case .contextShowReply:
|
|
SGSimpleSettings.shared.contextShowReply = value
|
|
case .contextShowPin:
|
|
SGSimpleSettings.shared.contextShowPin = value
|
|
case .contextShowSaveMedia:
|
|
SGSimpleSettings.shared.contextShowSaveMedia = value
|
|
case .contextShowMessageReplies:
|
|
SGSimpleSettings.shared.contextShowMessageReplies = value
|
|
case .stickerTimestamp:
|
|
SGSimpleSettings.shared.stickerTimestamp = value
|
|
case .contextShowJson:
|
|
SGSimpleSettings.shared.contextShowJson = value
|
|
case .hideRecordingButton:
|
|
SGSimpleSettings.shared.hideRecordingButton = !value
|
|
case .hideTabBar:
|
|
SGSimpleSettings.shared.hideTabBar = value
|
|
simplePromise.set(true) // Trigger update for 'enabled' field of other toggles
|
|
askForRestart?()
|
|
case .showDC:
|
|
SGSimpleSettings.shared.showDC = value
|
|
case .showCreationDate:
|
|
SGSimpleSettings.shared.showCreationDate = value
|
|
case .showRegDate:
|
|
SGSimpleSettings.shared.showRegDate = value
|
|
case .compactChatList:
|
|
SGSimpleSettings.shared.compactChatList = value
|
|
askForRestart?()
|
|
case .compactFolderNames:
|
|
SGSimpleSettings.shared.compactFolderNames = value
|
|
case .allChatsHidden:
|
|
SGSimpleSettings.shared.allChatsHidden = value
|
|
askForRestart?()
|
|
case .defaultEmojisFirst:
|
|
SGSimpleSettings.shared.defaultEmojisFirst = value
|
|
case .messageDoubleTapActionOutgoingEdit:
|
|
SGSimpleSettings.shared.messageDoubleTapActionOutgoing = value ? SGSimpleSettings.MessageDoubleTapAction.edit.rawValue : SGSimpleSettings.MessageDoubleTapAction.default.rawValue
|
|
case .wideChannelPosts:
|
|
SGSimpleSettings.shared.wideChannelPosts = value
|
|
case .forceEmojiTab:
|
|
SGSimpleSettings.shared.forceEmojiTab = value
|
|
case .forceBuiltInMic:
|
|
SGSimpleSettings.shared.forceBuiltInMic = value
|
|
case .hideChannelBottomButton:
|
|
SGSimpleSettings.shared.hideChannelBottomButton = !value
|
|
case .secondsInMessages:
|
|
SGSimpleSettings.shared.secondsInMessages = value
|
|
case .confirmCalls:
|
|
SGSimpleSettings.shared.confirmCalls = value
|
|
case .swipeForVideoPIP:
|
|
SGSimpleSettings.shared.videoPIPSwipeDirection = value ? SGSimpleSettings.VideoPIPSwipeDirection.up.rawValue : SGSimpleSettings.VideoPIPSwipeDirection.none.rawValue
|
|
}
|
|
}, updateSliderValue: { setting, value in
|
|
switch (setting) {
|
|
case .accountColorsSaturation:
|
|
if SGSimpleSettings.shared.accountColorsSaturation != value {
|
|
SGSimpleSettings.shared.accountColorsSaturation = value
|
|
simplePromise.set(true)
|
|
}
|
|
case .outgoingPhotoQuality:
|
|
if SGSimpleSettings.shared.outgoingPhotoQuality != value {
|
|
SGSimpleSettings.shared.outgoingPhotoQuality = value
|
|
simplePromise.set(true)
|
|
}
|
|
case .stickerSize:
|
|
if SGSimpleSettings.shared.stickerSize != value {
|
|
SGSimpleSettings.shared.stickerSize = value
|
|
simplePromise.set(true)
|
|
}
|
|
}
|
|
|
|
}, setOneFromManyValue: { setting in
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
let actionSheet = ActionSheetController(presentationData: presentationData)
|
|
var items: [ActionSheetItem] = []
|
|
|
|
switch (setting) {
|
|
case .downloadSpeedBoost:
|
|
let setAction: (String) -> Void = { value in
|
|
SGSimpleSettings.shared.downloadSpeedBoost = value
|
|
|
|
let enableDownloadX: Bool
|
|
switch (value) {
|
|
case SGSimpleSettings.DownloadSpeedBoostValues.none.rawValue:
|
|
enableDownloadX = false
|
|
default:
|
|
enableDownloadX = true
|
|
}
|
|
|
|
// Updating controller
|
|
simplePromise.set(true)
|
|
|
|
let _ = updateNetworkSettingsInteractively(postbox: context.account.postbox, network: context.account.network, { settings in
|
|
var settings = settings
|
|
settings.useExperimentalDownload = enableDownloadX
|
|
return settings
|
|
}).start(completed: {
|
|
Queue.mainQueue().async {
|
|
askForRestart?()
|
|
}
|
|
})
|
|
}
|
|
|
|
for value in SGSimpleSettings.DownloadSpeedBoostValues.allCases {
|
|
items.append(ActionSheetButtonItem(title: i18n("Settings.DownloadsBoost.\(value.rawValue)", presentationData.strings.baseLanguageCode), color: .accent, action: { [weak actionSheet] in
|
|
actionSheet?.dismissAnimated()
|
|
setAction(value.rawValue)
|
|
}))
|
|
}
|
|
case .bottomTabStyle:
|
|
let setAction: (String) -> Void = { value in
|
|
SGSimpleSettings.shared.bottomTabStyle = value
|
|
simplePromise.set(true)
|
|
}
|
|
|
|
for value in SGSimpleSettings.BottomTabStyleValues.allCases {
|
|
items.append(ActionSheetButtonItem(title: i18n("Settings.Folders.BottomTabStyle.\(value.rawValue)", presentationData.strings.baseLanguageCode), color: .accent, action: { [weak actionSheet] in
|
|
actionSheet?.dismissAnimated()
|
|
setAction(value.rawValue)
|
|
}))
|
|
}
|
|
case .allChatsTitleLengthOverride:
|
|
let setAction: (String) -> Void = { value in
|
|
SGSimpleSettings.shared.allChatsTitleLengthOverride = value
|
|
simplePromise.set(true)
|
|
}
|
|
|
|
for value in SGSimpleSettings.AllChatsTitleLengthOverride.allCases {
|
|
let title: String
|
|
switch (value) {
|
|
case SGSimpleSettings.AllChatsTitleLengthOverride.short:
|
|
title = "\"\(presentationData.strings.ChatList_Tabs_All)\""
|
|
case SGSimpleSettings.AllChatsTitleLengthOverride.long:
|
|
title = "\"\(presentationData.strings.ChatList_Tabs_AllChats)\""
|
|
default:
|
|
title = i18n("Settings.Folders.AllChatsTitle.none", presentationData.strings.baseLanguageCode)
|
|
}
|
|
items.append(ActionSheetButtonItem(title: title, color: .accent, action: { [weak actionSheet] in
|
|
actionSheet?.dismissAnimated()
|
|
setAction(value.rawValue)
|
|
}))
|
|
}
|
|
// case .allChatsFolderPositionOverride:
|
|
// let setAction: (String) -> Void = { value in
|
|
// SGSimpleSettings.shared.allChatsFolderPositionOverride = value
|
|
// simplePromise.set(true)
|
|
// }
|
|
//
|
|
// for value in SGSimpleSettings.AllChatsFolderPositionOverride.allCases {
|
|
// items.append(ActionSheetButtonItem(title: i18n("Settings.Folders.AllChatsTitle.\(value)", presentationData.strings.baseLanguageCode), color: .accent, action: { [weak actionSheet] in
|
|
// actionSheet?.dismissAnimated()
|
|
// setAction(value.rawValue)
|
|
// }))
|
|
// }
|
|
case .translationBackend:
|
|
let setAction: (String) -> Void = { value in
|
|
SGSimpleSettings.shared.translationBackend = value
|
|
simplePromise.set(true)
|
|
}
|
|
|
|
for value in SGSimpleSettings.TranslationBackend.allCases {
|
|
items.append(ActionSheetButtonItem(title: i18n("Settings.Translation.Backend.\(value.rawValue)", presentationData.strings.baseLanguageCode), color: .accent, action: { [weak actionSheet] in
|
|
actionSheet?.dismissAnimated()
|
|
setAction(value.rawValue)
|
|
}))
|
|
}
|
|
case .transcriptionBackend:
|
|
let setAction: (String) -> Void = { value in
|
|
SGSimpleSettings.shared.transcriptionBackend = value
|
|
simplePromise.set(true)
|
|
}
|
|
|
|
for value in SGSimpleSettings.TranscriptionBackend.allCases {
|
|
if #available(iOS 13.0, *) {
|
|
} else {
|
|
if value == .apple {
|
|
continue // Apple recognition is not available on iOS 12
|
|
}
|
|
}
|
|
items.append(ActionSheetButtonItem(title: i18n("Settings.Transcription.Backend.\(value.rawValue)", presentationData.strings.baseLanguageCode), color: .accent, action: { [weak actionSheet] in
|
|
actionSheet?.dismissAnimated()
|
|
setAction(value.rawValue)
|
|
}))
|
|
}
|
|
}
|
|
|
|
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
|
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
|
actionSheet?.dismissAnimated()
|
|
})
|
|
])])
|
|
presentControllerImpl?(actionSheet, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
|
}, openDisclosureLink: { link in
|
|
switch (link) {
|
|
case .languageSettings:
|
|
pushControllerImpl?(context.sharedContext.makeLocalizationListController(context: context))
|
|
case .contentSettings:
|
|
let _ = (getSGSettingsURL(context: context) |> deliverOnMainQueue).start(next: { [weak context] url in
|
|
guard let strongContext = context else {
|
|
return
|
|
}
|
|
strongContext.sharedContext.applicationBindings.openUrl(url)
|
|
})
|
|
}
|
|
}, searchInput: { searchQuery in
|
|
updateState { state in
|
|
var updatedState = state
|
|
updatedState.searchQuery = searchQuery
|
|
return updatedState
|
|
}
|
|
})
|
|
|
|
let sharedData = context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.callListSettings, ApplicationSpecificSharedDataKeys.experimentalUISettings])
|
|
let preferences = context.account.postbox.preferencesView(keys: [ApplicationSpecificPreferencesKeys.SGUISettings, PreferencesKeys.appConfiguration])
|
|
let updatedContentSettingsConfiguration = contentSettingsConfiguration(network: context.account.network)
|
|
|> map(Optional.init)
|
|
let contentSettingsConfiguration = Promise<ContentSettingsConfiguration?>()
|
|
contentSettingsConfiguration.set(.single(nil)
|
|
|> then(updatedContentSettingsConfiguration))
|
|
|
|
let signal = combineLatest(simplePromise.get(), /*sliderPromise.get(),*/ statePromise.get(), context.sharedContext.presentationData, sharedData, preferences, contentSettingsConfiguration.get(),
|
|
context.engine.accountData.observeAvailableColorOptions(scope: .replies),
|
|
context.engine.accountData.observeAvailableColorOptions(scope: .profile)
|
|
)
|
|
|> map { _, /*sliderValue,*/ state, presentationData, sharedData, view, contentSettingsConfiguration, availableReplyColors, availableProfileColors -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
|
|
|
let sgUISettings: SGUISettings = view.values[ApplicationSpecificPreferencesKeys.SGUISettings]?.get(SGUISettings.self) ?? SGUISettings.default
|
|
let appConfiguration: AppConfiguration = view.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) ?? AppConfiguration.defaultValue
|
|
let callListSettings: CallListSettings = sharedData.entries[ApplicationSpecificSharedDataKeys.callListSettings]?.get(CallListSettings.self) ?? CallListSettings.defaultSettings
|
|
let experimentalUISettings: ExperimentalUISettings = sharedData.entries[ApplicationSpecificSharedDataKeys.experimentalUISettings]?.get(ExperimentalUISettings.self) ?? ExperimentalUISettings.defaultSettings
|
|
|
|
let entries = SGControllerEntries(presentationData: presentationData, callListSettings: callListSettings, experimentalUISettings: experimentalUISettings, SGSettings: sgUISettings, appConfiguration: appConfiguration, nameColors: PeerNameColors.with(availableReplyColors: availableReplyColors, availableProfileColors: availableProfileColors), state: state)
|
|
|
|
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text("Swiftgram"), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
|
|
|
// TODO(swiftgram): focusOnItemTag support
|
|
/* var index = 0
|
|
var scrollToItem: ListViewScrollToItem?
|
|
if let focusOnItemTag = focusOnItemTag {
|
|
for entry in entries {
|
|
if entry.tag?.isEqual(to: focusOnItemTag) ?? false {
|
|
scrollToItem = ListViewScrollToItem(index: index, position: .top(0.0), animated: false, curve: .Default(duration: 0.0), directionHint: .Up)
|
|
}
|
|
index += 1
|
|
}
|
|
} */
|
|
|
|
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: entries, style: .blocks, ensureVisibleItemTag: /*focusOnItemTag*/ nil, initialScrollToItem: nil /* scrollToItem*/ )
|
|
|
|
return (controllerState, (listState, arguments))
|
|
}
|
|
|
|
let controller = ItemListController(context: context, state: signal)
|
|
presentControllerImpl = { [weak controller] c, a in
|
|
controller?.present(c, in: .window(.root), with: a)
|
|
}
|
|
pushControllerImpl = { [weak controller] c in
|
|
(controller?.navigationController as? NavigationController)?.pushViewController(c)
|
|
}
|
|
// getRootControllerImpl = { [weak controller] in
|
|
// return controller?.view.window?.rootViewController
|
|
// }
|
|
// getNavigationControllerImpl = { [weak controller] in
|
|
// return controller?.navigationController as? NavigationController
|
|
// }
|
|
askForRestart = { [weak context] in
|
|
guard let context = context else {
|
|
return
|
|
}
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
presentControllerImpl?(
|
|
UndoOverlayController(
|
|
presentationData: presentationData,
|
|
content: .info(title: nil, // i18n("Common.RestartRequired", presentationData.strings.baseLanguageCode),
|
|
text: i18n("Common.RestartRequired", presentationData.strings.baseLanguageCode),
|
|
timeout: nil,
|
|
customUndoText: i18n("Common.RestartNow", presentationData.strings.baseLanguageCode) //presentationData.strings.Common_Yes
|
|
),
|
|
elevatedLayout: false,
|
|
action: { action in if action == .undo { exit(0) }; return true }
|
|
),
|
|
nil
|
|
)
|
|
}
|
|
return controller
|
|
|
|
}
|