mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
534 lines
27 KiB
Swift
534 lines
27 KiB
Swift
import Foundation
|
|
import UIKit
|
|
import Display
|
|
import SwiftSignalKit
|
|
import Postbox
|
|
import TelegramCore
|
|
import TelegramPresentationData
|
|
import TelegramUIPreferences
|
|
import ItemListUI
|
|
import OverlayStatusController
|
|
import AccountContext
|
|
import AlertUI
|
|
import TelegramNotices
|
|
|
|
private final class DataPrivacyControllerArguments {
|
|
let account: Account
|
|
let clearPaymentInfo: () -> Void
|
|
let updateSecretChatLinkPreviews: (Bool) -> Void
|
|
let deleteContacts: () -> Void
|
|
let updateSyncContacts: (Bool) -> Void
|
|
let updateSuggestFrequentContacts: (Bool) -> Void
|
|
let deleteCloudDrafts: () -> Void
|
|
|
|
init(account: Account, clearPaymentInfo: @escaping () -> Void, updateSecretChatLinkPreviews: @escaping (Bool) -> Void, deleteContacts: @escaping () -> Void, updateSyncContacts: @escaping (Bool) -> Void, updateSuggestFrequentContacts: @escaping (Bool) -> Void, deleteCloudDrafts: @escaping () -> Void) {
|
|
self.account = account
|
|
self.clearPaymentInfo = clearPaymentInfo
|
|
self.updateSecretChatLinkPreviews = updateSecretChatLinkPreviews
|
|
self.deleteContacts = deleteContacts
|
|
self.updateSyncContacts = updateSyncContacts
|
|
self.updateSuggestFrequentContacts = updateSuggestFrequentContacts
|
|
self.deleteCloudDrafts = deleteCloudDrafts
|
|
}
|
|
}
|
|
|
|
private enum PrivacyAndSecuritySection: Int32 {
|
|
case contacts
|
|
case frequentContacts
|
|
case chats
|
|
case payments
|
|
case secretChats
|
|
}
|
|
|
|
private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
|
|
case contactsHeader(PresentationTheme, String)
|
|
case deleteContacts(PresentationTheme, String, Bool)
|
|
case syncContacts(PresentationTheme, String, Bool)
|
|
case syncContactsInfo(PresentationTheme, String)
|
|
|
|
case frequentContacts(PresentationTheme, String, Bool)
|
|
case frequentContactsInfo(PresentationTheme, String)
|
|
|
|
case chatsHeader(PresentationTheme, String)
|
|
case deleteCloudDrafts(PresentationTheme, String, Bool)
|
|
|
|
case paymentHeader(PresentationTheme, String)
|
|
case clearPaymentInfo(PresentationTheme, String, Bool)
|
|
case paymentInfo(PresentationTheme, String)
|
|
|
|
case secretChatLinkPreviewsHeader(PresentationTheme, String)
|
|
case secretChatLinkPreviews(PresentationTheme, String, Bool)
|
|
case secretChatLinkPreviewsInfo(PresentationTheme, String)
|
|
|
|
var section: ItemListSectionId {
|
|
switch self {
|
|
case .contactsHeader, .deleteContacts, .syncContacts, .syncContactsInfo:
|
|
return PrivacyAndSecuritySection.contacts.rawValue
|
|
case .frequentContacts, .frequentContactsInfo:
|
|
return PrivacyAndSecuritySection.frequentContacts.rawValue
|
|
case .chatsHeader, .deleteCloudDrafts:
|
|
return PrivacyAndSecuritySection.chats.rawValue
|
|
case .paymentHeader, .clearPaymentInfo, .paymentInfo:
|
|
return PrivacyAndSecuritySection.payments.rawValue
|
|
case .secretChatLinkPreviewsHeader, .secretChatLinkPreviews, .secretChatLinkPreviewsInfo:
|
|
return PrivacyAndSecuritySection.secretChats.rawValue
|
|
|
|
}
|
|
}
|
|
|
|
var stableId: Int32 {
|
|
switch self {
|
|
case .contactsHeader:
|
|
return 0
|
|
case .deleteContacts:
|
|
return 1
|
|
case .syncContacts:
|
|
return 2
|
|
case .syncContactsInfo:
|
|
return 3
|
|
|
|
case .frequentContacts:
|
|
return 4
|
|
case .frequentContactsInfo:
|
|
return 5
|
|
|
|
case .chatsHeader:
|
|
return 6
|
|
case .deleteCloudDrafts:
|
|
return 7
|
|
|
|
case .paymentHeader:
|
|
return 8
|
|
case .clearPaymentInfo:
|
|
return 9
|
|
case .paymentInfo:
|
|
return 10
|
|
|
|
case .secretChatLinkPreviewsHeader:
|
|
return 11
|
|
case .secretChatLinkPreviews:
|
|
return 12
|
|
case .secretChatLinkPreviewsInfo:
|
|
return 13
|
|
}
|
|
}
|
|
|
|
static func ==(lhs: PrivacyAndSecurityEntry, rhs: PrivacyAndSecurityEntry) -> Bool {
|
|
switch lhs {
|
|
case let .contactsHeader(lhsTheme, lhsText):
|
|
if case let .contactsHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .deleteContacts(lhsTheme, lhsText, lhsEnabled):
|
|
if case let .deleteContacts(rhsTheme, rhsText, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsEnabled == rhsEnabled {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .syncContacts(lhsTheme, lhsText, lhsEnabled):
|
|
if case let .syncContacts(rhsTheme, rhsText, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsEnabled == rhsEnabled {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .syncContactsInfo(lhsTheme, lhsText):
|
|
if case let .syncContactsInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .frequentContacts(lhsTheme, lhsText, lhsEnabled):
|
|
if case let .frequentContacts(rhsTheme, rhsText, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsEnabled == rhsEnabled {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .frequentContactsInfo(lhsTheme, lhsText):
|
|
if case let .frequentContactsInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .chatsHeader(lhsTheme, lhsText):
|
|
if case let .chatsHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .deleteCloudDrafts(lhsTheme, lhsText, lhsEnabled):
|
|
if case let .deleteCloudDrafts(rhsTheme, rhsText, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsEnabled == rhsEnabled {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .paymentHeader(lhsTheme, lhsText):
|
|
if case let .paymentHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .clearPaymentInfo(lhsTheme, lhsText, lhsEnabled):
|
|
if case let .clearPaymentInfo(rhsTheme, rhsText, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsEnabled == rhsEnabled {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .paymentInfo(lhsTheme, lhsText):
|
|
if case let .paymentInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .secretChatLinkPreviewsHeader(lhsTheme, lhsText):
|
|
if case let .secretChatLinkPreviewsHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .secretChatLinkPreviews(lhsTheme, lhsText, lhsEnabled):
|
|
if case let .secretChatLinkPreviews(rhsTheme, rhsText, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsEnabled == rhsEnabled {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
case let .secretChatLinkPreviewsInfo(lhsTheme, lhsText):
|
|
if case let .secretChatLinkPreviewsInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
static func <(lhs: PrivacyAndSecurityEntry, rhs: PrivacyAndSecurityEntry) -> Bool {
|
|
return lhs.stableId < rhs.stableId
|
|
}
|
|
|
|
func item(_ arguments: DataPrivacyControllerArguments) -> ListViewItem {
|
|
switch self {
|
|
case let .contactsHeader(theme, text):
|
|
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
|
case let .deleteContacts(theme, text, value):
|
|
return ItemListActionItem(theme: theme, title: text, kind: value ? .generic : .disabled, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
|
arguments.deleteContacts()
|
|
})
|
|
case let .syncContacts(theme, text, value):
|
|
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
|
|
arguments.updateSyncContacts(updatedValue)
|
|
})
|
|
case let .syncContactsInfo(theme, text):
|
|
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
|
|
case let .frequentContacts(theme, text, value):
|
|
return ItemListSwitchItem(theme: theme, title: text, value: value, enableInteractiveChanges: !value, sectionId: self.section, style: .blocks, updated: { updatedValue in
|
|
arguments.updateSuggestFrequentContacts(updatedValue)
|
|
})
|
|
case let .frequentContactsInfo(theme, text):
|
|
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
|
|
case let .chatsHeader(theme, text):
|
|
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
|
case let .deleteCloudDrafts(theme, text, value):
|
|
return ItemListActionItem(theme: theme, title: text, kind: value ? .generic : .disabled, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
|
arguments.deleteCloudDrafts()
|
|
})
|
|
case let .paymentHeader(theme, text):
|
|
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
|
case let .clearPaymentInfo(theme, text, enabled):
|
|
return ItemListActionItem(theme: theme, title: text, kind: enabled ? .generic : .disabled, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
|
arguments.clearPaymentInfo()
|
|
})
|
|
case let .paymentInfo(theme, text):
|
|
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
|
|
case let .secretChatLinkPreviewsHeader(theme, text):
|
|
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
|
case let .secretChatLinkPreviews(theme, text, value):
|
|
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
|
|
arguments.updateSecretChatLinkPreviews(updatedValue)
|
|
})
|
|
case let .secretChatLinkPreviewsInfo(theme, text):
|
|
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct DataPrivacyControllerState: Equatable {
|
|
var clearingPaymentInfo: Bool = false
|
|
var deletingContacts: Bool = false
|
|
var updatedSuggestFrequentContacts: Bool? = nil
|
|
var deletingCloudDrafts: Bool = false
|
|
}
|
|
|
|
private func dataPrivacyControllerEntries(presentationData: PresentationData, state: DataPrivacyControllerState, secretChatLinkPreviews: Bool?, synchronizeDeviceContacts: Bool, frequentContacts: Bool) -> [PrivacyAndSecurityEntry] {
|
|
var entries: [PrivacyAndSecurityEntry] = []
|
|
|
|
entries.append(.contactsHeader(presentationData.theme, presentationData.strings.Privacy_ContactsTitle))
|
|
entries.append(.deleteContacts(presentationData.theme, presentationData.strings.Privacy_ContactsReset, !state.deletingContacts))
|
|
entries.append(.syncContacts(presentationData.theme, presentationData.strings.Privacy_ContactsSync, synchronizeDeviceContacts))
|
|
entries.append(.syncContactsInfo(presentationData.theme, presentationData.strings.Privacy_ContactsSyncHelp))
|
|
|
|
entries.append(.frequentContacts(presentationData.theme, presentationData.strings.Privacy_TopPeers, frequentContacts))
|
|
entries.append(.frequentContactsInfo(presentationData.theme, presentationData.strings.Privacy_TopPeersHelp))
|
|
|
|
entries.append(.chatsHeader(presentationData.theme, presentationData.strings.Privacy_ChatsTitle))
|
|
entries.append(.deleteCloudDrafts(presentationData.theme, presentationData.strings.Privacy_DeleteDrafts, !state.deletingCloudDrafts))
|
|
entries.append(.paymentHeader(presentationData.theme, presentationData.strings.Privacy_PaymentsTitle))
|
|
entries.append(.clearPaymentInfo(presentationData.theme, presentationData.strings.Privacy_PaymentsClearInfo, !state.clearingPaymentInfo))
|
|
entries.append(.paymentInfo(presentationData.theme, presentationData.strings.Privacy_PaymentsClearInfoHelp))
|
|
|
|
entries.append(.secretChatLinkPreviewsHeader(presentationData.theme, presentationData.strings.Privacy_SecretChatsTitle))
|
|
entries.append(.secretChatLinkPreviews(presentationData.theme, presentationData.strings.Privacy_SecretChatsLinkPreviews, secretChatLinkPreviews ?? true))
|
|
entries.append(.secretChatLinkPreviewsInfo(presentationData.theme, presentationData.strings.Privacy_SecretChatsLinkPreviewsHelp))
|
|
|
|
return entries
|
|
}
|
|
|
|
public func dataPrivacyController(context: AccountContext) -> ViewController {
|
|
let statePromise = ValuePromise(DataPrivacyControllerState(), ignoreRepeated: true)
|
|
let stateValue = Atomic(value: DataPrivacyControllerState())
|
|
let updateState: ((DataPrivacyControllerState) -> DataPrivacyControllerState) -> Void = { f in
|
|
statePromise.set(stateValue.modify { f($0) })
|
|
}
|
|
|
|
var presentControllerImpl: ((ViewController) -> Void)?
|
|
|
|
let actionsDisposable = DisposableSet()
|
|
|
|
let currentInfoDisposable = MetaDisposable()
|
|
actionsDisposable.add(currentInfoDisposable)
|
|
|
|
let clearPaymentInfoDisposable = MetaDisposable()
|
|
actionsDisposable.add(clearPaymentInfoDisposable)
|
|
|
|
let arguments = DataPrivacyControllerArguments(account: context.account, clearPaymentInfo: {
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
let controller = ActionSheetController(presentationTheme: presentationData.theme)
|
|
let dismissAction: () -> Void = { [weak controller] in
|
|
controller?.dismissAnimated()
|
|
}
|
|
|
|
var values = [true, true]
|
|
|
|
let toggleCheck: (Int) -> Void = { [weak controller] itemIndex in
|
|
controller?.updateItem(groupIndex: 0, itemIndex: itemIndex, { item in
|
|
if let item = item as? ActionSheetCheckboxItem {
|
|
values[itemIndex] = !item.value
|
|
return ActionSheetCheckboxItem(title: item.title, label: item.label, value: !item.value, action: item.action)
|
|
}
|
|
return item
|
|
})
|
|
|
|
controller?.updateItem(groupIndex: 0, itemIndex: 2, { item in
|
|
if let item = item as? ActionSheetButtonItem {
|
|
let disabled = !values[0] && !values[1]
|
|
return ActionSheetButtonItem(title: item.title, color: disabled ? .disabled : .accent, enabled: !disabled, action: item.action)
|
|
}
|
|
return item
|
|
})
|
|
}
|
|
|
|
var items: [ActionSheetItem] = []
|
|
|
|
items.append(ActionSheetCheckboxItem(title: presentationData.strings.Privacy_PaymentsClear_PaymentInfo, label: "", value: true, action: { value in
|
|
toggleCheck(0)
|
|
}))
|
|
|
|
items.append(ActionSheetCheckboxItem(title: presentationData.strings.Privacy_PaymentsClear_ShippingInfo, label: "", value: true, action: { value in
|
|
toggleCheck(1)
|
|
}))
|
|
|
|
items.append(ActionSheetButtonItem(title: presentationData.strings.Cache_ClearNone, action: {
|
|
var clear = false
|
|
updateState { state in
|
|
var state = state
|
|
if !state.clearingPaymentInfo {
|
|
clear = true
|
|
state.clearingPaymentInfo = true
|
|
}
|
|
return state
|
|
}
|
|
if clear {
|
|
var info = BotPaymentInfo()
|
|
if values[0] {
|
|
info.insert(.paymentInfo)
|
|
}
|
|
if values[1] {
|
|
info.insert(.shippingInfo)
|
|
}
|
|
|
|
clearPaymentInfoDisposable.set((clearBotPaymentInfo(network: context.account.network, info: info)
|
|
|> deliverOnMainQueue).start(completed: {
|
|
updateState { state in
|
|
var state = state
|
|
state.clearingPaymentInfo = false
|
|
return state
|
|
}
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .success))
|
|
}))
|
|
}
|
|
dismissAction()
|
|
}))
|
|
|
|
controller.setItemGroups([
|
|
ActionSheetItemGroup(items: items),
|
|
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])
|
|
])
|
|
presentControllerImpl?(controller)
|
|
}, updateSecretChatLinkPreviews: { value in
|
|
let _ = ApplicationSpecificNotice.setSecretChatLinkPreviews(accountManager: context.sharedContext.accountManager, value: value).start()
|
|
}, deleteContacts: {
|
|
var canBegin = false
|
|
updateState { state in
|
|
if !state.deletingContacts {
|
|
canBegin = true
|
|
}
|
|
return state
|
|
}
|
|
if canBegin {
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Privacy_ContactsResetConfirmation, actions: [TextAlertAction(type: .destructiveAction, title: presentationData.strings.Common_Delete, action: {
|
|
var begin = false
|
|
updateState { state in
|
|
var state = state
|
|
if !state.deletingContacts {
|
|
state.deletingContacts = true
|
|
begin = true
|
|
}
|
|
return state
|
|
}
|
|
|
|
if !begin {
|
|
return
|
|
}
|
|
|
|
let _ = context.account.postbox.transaction({ transaction in
|
|
transaction.updatePreferencesEntry(key: PreferencesKeys.contactsSettings, { current in
|
|
var settings = current as? ContactsSettings ?? ContactsSettings.defaultSettings
|
|
settings.synchronizeContacts = false
|
|
return settings
|
|
})
|
|
}).start()
|
|
|
|
actionsDisposable.add((deleteAllContacts(account: context.account)
|
|
|> deliverOnMainQueue).start(completed: {
|
|
updateState { state in
|
|
var state = state
|
|
state.deletingContacts = false
|
|
return state
|
|
}
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .success))
|
|
}))
|
|
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {})]))
|
|
}
|
|
}, updateSyncContacts: { value in
|
|
let _ = context.account.postbox.transaction({ transaction in
|
|
transaction.updatePreferencesEntry(key: PreferencesKeys.contactsSettings, { current in
|
|
var settings = current as? ContactsSettings ?? ContactsSettings.defaultSettings
|
|
settings.synchronizeContacts = value
|
|
return settings
|
|
})
|
|
}).start()
|
|
}, updateSuggestFrequentContacts: { value in
|
|
let apply: () -> Void = {
|
|
updateState { state in
|
|
var state = state
|
|
state.updatedSuggestFrequentContacts = value
|
|
return state
|
|
}
|
|
let _ = updateRecentPeersEnabled(postbox: context.account.postbox, network: context.account.network, enabled: value).start()
|
|
}
|
|
if !value {
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
presentControllerImpl?(textAlertController(context: context, title: nil, text: presentationData.strings.Privacy_TopPeersWarning, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
|
|
apply()
|
|
})]))
|
|
} else {
|
|
apply()
|
|
}
|
|
}, deleteCloudDrafts: {
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
let controller = ActionSheetController(presentationTheme: presentationData.theme)
|
|
let dismissAction: () -> Void = { [weak controller] in
|
|
controller?.dismissAnimated()
|
|
}
|
|
controller.setItemGroups([
|
|
ActionSheetItemGroup(items: [
|
|
ActionSheetButtonItem(title: presentationData.strings.Privacy_DeleteDrafts, color: .destructive, action: {
|
|
var clear = false
|
|
updateState { state in
|
|
var state = state
|
|
if !state.deletingCloudDrafts {
|
|
clear = true
|
|
state.deletingCloudDrafts = true
|
|
}
|
|
return state
|
|
}
|
|
if clear {
|
|
clearPaymentInfoDisposable.set((clearCloudDraftsInteractively(postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId)
|
|
|> deliverOnMainQueue).start(completed: {
|
|
updateState { state in
|
|
var state = state
|
|
state.deletingCloudDrafts = false
|
|
return state
|
|
}
|
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .success))
|
|
}))
|
|
}
|
|
dismissAction()
|
|
})
|
|
]),
|
|
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])
|
|
])
|
|
presentControllerImpl?(controller)
|
|
})
|
|
|
|
let previousState = Atomic<DataPrivacyControllerState?>(value: nil)
|
|
|
|
actionsDisposable.add(managedUpdatedRecentPeers(accountPeerId: context.account.peerId, postbox: context.account.postbox, network: context.account.network).start())
|
|
|
|
let signal = combineLatest(queue: .mainQueue(), context.sharedContext.presentationData, statePromise.get(), context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.secretChatLinkPreviewsKey()), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]), context.account.postbox.preferencesView(keys: [PreferencesKeys.contactsSettings]), recentPeers(account: context.account))
|
|
|> map { presentationData, state, noticeView, sharedData, preferences, recentPeers -> (ItemListControllerState, (ItemListNodeState<PrivacyAndSecurityEntry>, PrivacyAndSecurityEntry.ItemGenerationArguments)) in
|
|
let secretChatLinkPreviews = noticeView.value.flatMap({ ApplicationSpecificNotice.getSecretChatLinkPreviews($0) })
|
|
|
|
let settings: ContactsSettings = preferences.values[PreferencesKeys.contactsSettings] as? ContactsSettings ?? ContactsSettings.defaultSettings
|
|
|
|
let synchronizeDeviceContacts: Bool = settings.synchronizeContacts
|
|
|
|
let suggestRecentPeers: Bool
|
|
if let updatedSuggestFrequentContacts = state.updatedSuggestFrequentContacts {
|
|
suggestRecentPeers = updatedSuggestFrequentContacts
|
|
} else {
|
|
switch recentPeers {
|
|
case .peers:
|
|
suggestRecentPeers = true
|
|
case .disabled:
|
|
suggestRecentPeers = false
|
|
}
|
|
}
|
|
|
|
let rightNavigationButton: ItemListNavigationButton? = nil
|
|
|
|
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text(presentationData.strings.PrivateDataSettings_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
|
|
|
let previousStateValue = previousState.swap(state)
|
|
let animateChanges = false
|
|
|
|
let listState = ItemListNodeState(entries: dataPrivacyControllerEntries(presentationData: presentationData, state: state, secretChatLinkPreviews: secretChatLinkPreviews, synchronizeDeviceContacts: synchronizeDeviceContacts, frequentContacts: suggestRecentPeers), style: .blocks, animateChanges: animateChanges)
|
|
|
|
return (controllerState, (listState, arguments))
|
|
}
|
|
|> afterDisposed {
|
|
actionsDisposable.dispose()
|
|
}
|
|
|
|
let controller = ItemListController(context: context, state: signal)
|
|
presentControllerImpl = { [weak controller] c in
|
|
controller?.present(c, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
|
}
|
|
|
|
return controller
|
|
}
|