mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-17 03:40:18 +00:00
Move contacts sync settings back to individual accounts
This commit is contained in:
parent
5b04bba7b2
commit
55aa20c2a5
@ -134,10 +134,10 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
}).start()
|
}).start()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
controller.loginWithNumber = { [weak self, weak controller] number in
|
controller.loginWithNumber = { [weak self, weak controller] number, syncContacts in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
controller?.inProgress = true
|
controller?.inProgress = true
|
||||||
strongSelf.actionDisposable.set((sendAuthorizationCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, phoneNumber: number, apiId: strongSelf.apiId, apiHash: strongSelf.apiHash) |> deliverOnMainQueue).start(next: { [weak self] account in
|
strongSelf.actionDisposable.set((sendAuthorizationCode(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, phoneNumber: number, apiId: strongSelf.apiId, apiHash: strongSelf.apiHash, syncContacts: syncContacts) |> deliverOnMainQueue).start(next: { [weak self] account in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
controller?.inProgress = false
|
controller?.inProgress = false
|
||||||
strongSelf.account = account
|
strongSelf.account = account
|
||||||
@ -399,7 +399,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
return controller
|
return controller
|
||||||
}
|
}
|
||||||
|
|
||||||
private func passwordEntryController(hint: String, suggestReset: Bool) -> AuthorizationSequencePasswordEntryController {
|
private func passwordEntryController(hint: String, suggestReset: Bool, syncContacts: Bool) -> AuthorizationSequencePasswordEntryController {
|
||||||
var currentController: AuthorizationSequencePasswordEntryController?
|
var currentController: AuthorizationSequencePasswordEntryController?
|
||||||
for c in self.viewControllers {
|
for c in self.viewControllers {
|
||||||
if let c = c as? AuthorizationSequencePasswordEntryController {
|
if let c = c as? AuthorizationSequencePasswordEntryController {
|
||||||
@ -425,7 +425,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
controller?.inProgress = true
|
controller?.inProgress = true
|
||||||
|
|
||||||
strongSelf.actionDisposable.set((authorizeWithPassword(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, password: password) |> deliverOnMainQueue).start(error: { error in
|
strongSelf.actionDisposable.set((authorizeWithPassword(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, password: password, syncContacts: syncContacts) |> deliverOnMainQueue).start(error: { error in
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
if let strongSelf = self, let controller = controller {
|
if let strongSelf = self, let controller = controller {
|
||||||
controller.inProgress = false
|
controller.inProgress = false
|
||||||
@ -458,8 +458,8 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
switch option {
|
switch option {
|
||||||
case let .email(pattern):
|
case let .email(pattern):
|
||||||
let _ = (strongSelf.account.postbox.transaction { transaction -> Void in
|
let _ = (strongSelf.account.postbox.transaction { transaction -> Void in
|
||||||
if let state = transaction.getState() as? UnauthorizedAccountState, case let .passwordEntry(hint, number, code, _) = state.contents {
|
if let state = transaction.getState() as? UnauthorizedAccountState, case let .passwordEntry(hint, number, code, _, syncContacts) = state.contents {
|
||||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordRecovery(hint: hint, number: number, code: code, emailPattern: pattern)))
|
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: strongSelf.account.testingEnvironment, masterDatacenterId: strongSelf.account.masterDatacenterId, contents: .passwordRecovery(hint: hint, number: number, code: code, emailPattern: pattern, syncContacts: syncContacts)))
|
||||||
}
|
}
|
||||||
}).start()
|
}).start()
|
||||||
case .none:
|
case .none:
|
||||||
@ -507,7 +507,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
return controller
|
return controller
|
||||||
}
|
}
|
||||||
|
|
||||||
private func passwordRecoveryController(emailPattern: String) -> AuthorizationSequencePasswordRecoveryController {
|
private func passwordRecoveryController(emailPattern: String, syncContacts: Bool) -> AuthorizationSequencePasswordRecoveryController {
|
||||||
var currentController: AuthorizationSequencePasswordRecoveryController?
|
var currentController: AuthorizationSequencePasswordRecoveryController?
|
||||||
for c in self.viewControllers {
|
for c in self.viewControllers {
|
||||||
if let c = c as? AuthorizationSequencePasswordRecoveryController {
|
if let c = c as? AuthorizationSequencePasswordRecoveryController {
|
||||||
@ -533,7 +533,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
controller?.inProgress = true
|
controller?.inProgress = true
|
||||||
|
|
||||||
strongSelf.actionDisposable.set((performPasswordRecovery(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, code: code) |> deliverOnMainQueue).start(error: { error in
|
strongSelf.actionDisposable.set((performPasswordRecovery(accountManager: strongSelf.sharedContext.accountManager, account: strongSelf.account, code: code, syncContacts: syncContacts) |> deliverOnMainQueue).start(error: { error in
|
||||||
Queue.mainQueue().async {
|
Queue.mainQueue().async {
|
||||||
if let strongSelf = self, let controller = controller {
|
if let strongSelf = self, let controller = controller {
|
||||||
controller.inProgress = false
|
controller.inProgress = false
|
||||||
@ -559,8 +559,8 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
controller.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.theme), title: nil, text: strongSelf.strings.TwoStepAuth_RecoveryFailed, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.strings.Common_OK, action: {})]), in: .window(.root))
|
controller.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: strongSelf.theme), title: nil, text: strongSelf.strings.TwoStepAuth_RecoveryFailed, actions: [TextAlertAction(type: .defaultAction, title: strongSelf.strings.Common_OK, action: {})]), in: .window(.root))
|
||||||
let account = strongSelf.account
|
let account = strongSelf.account
|
||||||
let _ = (strongSelf.account.postbox.transaction { transaction -> Void in
|
let _ = (strongSelf.account.postbox.transaction { transaction -> Void in
|
||||||
if let state = transaction.getState() as? UnauthorizedAccountState, case let .passwordRecovery(hint, number, code, _) = state.contents {
|
if let state = transaction.getState() as? UnauthorizedAccountState, case let .passwordRecovery(hint, number, code, _, syncContacts) = state.contents {
|
||||||
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code, suggestReset: true)))
|
transaction.setState(UnauthorizedAccountState(isTestingEnvironment: account.testingEnvironment, masterDatacenterId: account.masterDatacenterId, contents: .passwordEntry(hint: hint, number: number, code: code, suggestReset: true, syncContacts: syncContacts)))
|
||||||
}
|
}
|
||||||
}).start()
|
}).start()
|
||||||
}
|
}
|
||||||
@ -715,7 +715,7 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
}
|
}
|
||||||
controllers.append(self.phoneEntryController(countryCode: countryCode, number: number))
|
controllers.append(self.phoneEntryController(countryCode: countryCode, number: number))
|
||||||
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
||||||
case let .confirmationCodeEntry(number, type, _, timeout, nextType, termsOfService):
|
case let .confirmationCodeEntry(number, type, _, timeout, nextType, termsOfService, syncContacts):
|
||||||
var controllers: [ViewController] = []
|
var controllers: [ViewController] = []
|
||||||
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
||||||
controllers.append(self.splashController())
|
controllers.append(self.splashController())
|
||||||
@ -723,28 +723,28 @@ public final class AuthorizationSequenceController: NavigationController, MFMail
|
|||||||
controllers.append(self.phoneEntryController(countryCode: defaultCountryCode(), number: ""))
|
controllers.append(self.phoneEntryController(countryCode: defaultCountryCode(), number: ""))
|
||||||
controllers.append(self.codeEntryController(number: number, type: type, nextType: nextType, timeout: timeout, termsOfService: termsOfService))
|
controllers.append(self.codeEntryController(number: number, type: type, nextType: nextType, timeout: timeout, termsOfService: termsOfService))
|
||||||
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
||||||
case let .passwordEntry(hint, _, _, suggestReset):
|
case let .passwordEntry(hint, _, _, suggestReset, syncContacts):
|
||||||
var controllers: [ViewController] = []
|
var controllers: [ViewController] = []
|
||||||
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
||||||
controllers.append(self.splashController())
|
controllers.append(self.splashController())
|
||||||
}
|
}
|
||||||
controllers.append(self.passwordEntryController(hint: hint, suggestReset: suggestReset))
|
controllers.append(self.passwordEntryController(hint: hint, suggestReset: suggestReset, syncContacts: syncContacts))
|
||||||
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
||||||
case let .passwordRecovery(_, _, _, emailPattern):
|
case let .passwordRecovery(_, _, _, emailPattern, syncContacts):
|
||||||
var controllers: [ViewController] = []
|
var controllers: [ViewController] = []
|
||||||
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
||||||
controllers.append(self.splashController())
|
controllers.append(self.splashController())
|
||||||
}
|
}
|
||||||
controllers.append(self.passwordRecoveryController(emailPattern: emailPattern))
|
controllers.append(self.passwordRecoveryController(emailPattern: emailPattern, syncContacts: syncContacts))
|
||||||
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
||||||
case let .awaitingAccountReset(protectedUntil, number):
|
case let .awaitingAccountReset(protectedUntil, number, _):
|
||||||
var controllers: [ViewController] = []
|
var controllers: [ViewController] = []
|
||||||
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
||||||
controllers.append(self.splashController())
|
controllers.append(self.splashController())
|
||||||
}
|
}
|
||||||
controllers.append(self.awaitingAccountResetController(protectedUntil: protectedUntil, number: number))
|
controllers.append(self.awaitingAccountResetController(protectedUntil: protectedUntil, number: number))
|
||||||
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
self.setViewControllers(controllers, animated: !self.viewControllers.isEmpty)
|
||||||
case let .signUp(_, _, _, firstName, lastName, termsOfService):
|
case let .signUp(_, _, _, firstName, lastName, termsOfService, syncContacts):
|
||||||
var controllers: [ViewController] = []
|
var controllers: [ViewController] = []
|
||||||
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
if !self.otherAccountPhoneNumbers.1.isEmpty {
|
||||||
controllers.append(self.splashController())
|
controllers.append(self.splashController())
|
||||||
|
|||||||
@ -33,7 +33,7 @@ final class AuthorizationSequencePhoneEntryController: ViewController {
|
|||||||
self.controllerNode.inProgress = self.inProgress
|
self.controllerNode.inProgress = self.inProgress
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var loginWithNumber: ((String) -> Void)?
|
var loginWithNumber: ((String, Bool) -> Void)?
|
||||||
|
|
||||||
private let termsDisposable = MetaDisposable()
|
private let termsDisposable = MetaDisposable()
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ final class AuthorizationSequencePhoneEntryController: ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
self?.present(debugController(sharedContext: strongSelf.sharedContext, context: nil, modal: true), in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
self?.present(debugController(sharedContext: strongSelf.sharedContext, context: nil, modal: true), in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
})
|
}, hasOtherAccounts: self.otherAccountPhoneNumbers.0 != nil)
|
||||||
if let (code, name, number) = self.currentData {
|
if let (code, name, number) = self.currentData {
|
||||||
self.controllerNode.codeAndNumber = (code, name, number)
|
self.controllerNode.codeAndNumber = (code, name, number)
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ final class AuthorizationSequencePhoneEntryController: ViewController {
|
|||||||
actions.append(TextAlertAction(type: .defaultAction, title: self.strings.Common_OK, action: {}))
|
actions.append(TextAlertAction(type: .defaultAction, title: self.strings.Common_OK, action: {}))
|
||||||
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: self.theme), title: nil, text: self.strings.Login_PhoneNumberAlreadyAuthorized, actions: actions), in: .window(.root))
|
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: self.theme), title: nil, text: self.strings.Login_PhoneNumberAlreadyAuthorized, actions: actions), in: .window(.root))
|
||||||
} else {
|
} else {
|
||||||
self.loginWithNumber?(self.controllerNode.currentNumber)
|
self.loginWithNumber?(self.controllerNode.currentNumber, self.controllerNode.syncContacts)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hapticFeedback.error()
|
hapticFeedback.error()
|
||||||
|
|||||||
@ -162,14 +162,42 @@ private final class PhoneAndCountryNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class ContactSyncNode: ASDisplayNode {
|
||||||
|
private let titleNode: ImmediateTextNode
|
||||||
|
let switchNode: SwitchNode
|
||||||
|
|
||||||
|
init(theme: PresentationTheme, strings: PresentationStrings) {
|
||||||
|
self.titleNode = ImmediateTextNode()
|
||||||
|
self.titleNode.maximumNumberOfLines = 1
|
||||||
|
self.titleNode.attributedText = NSAttributedString(string: strings.Privacy_ContactsSync, font: Font.regular(17.0), textColor: theme.list.itemPrimaryTextColor)
|
||||||
|
self.switchNode = SwitchNode()
|
||||||
|
self.switchNode.isOn = true
|
||||||
|
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.addSubnode(self.titleNode)
|
||||||
|
self.addSubnode(self.switchNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateLayout(width: CGFloat) -> CGSize {
|
||||||
|
let switchSize = CGSize(width: 51.0, height: 31.0)
|
||||||
|
let titleSize = self.titleNode.updateLayout(CGSize(width: width - switchSize.width - 16.0 * 2.0 - 8.0, height: .greatestFiniteMagnitude))
|
||||||
|
let height: CGFloat = 40.0
|
||||||
|
self.titleNode.frame = CGRect(origin: CGPoint(x: 16.0, y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||||
|
self.switchNode.frame = CGRect(origin: CGPoint(x: width - 16.0 - switchSize.width, y: floor((height - switchSize.height) / 2.0)), size: switchSize)
|
||||||
|
return CGSize(width: width, height: height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
||||||
private let strings: PresentationStrings
|
private let strings: PresentationStrings
|
||||||
private let theme: PresentationTheme
|
private let theme: PresentationTheme
|
||||||
|
private let hasOtherAccounts: Bool
|
||||||
|
|
||||||
private let titleNode: ASTextNode
|
private let titleNode: ASTextNode
|
||||||
private let noticeNode: ASTextNode
|
private let noticeNode: ASTextNode
|
||||||
private let phoneAndCountryNode: PhoneAndCountryNode
|
private let phoneAndCountryNode: PhoneAndCountryNode
|
||||||
private let termsOfServiceNode: ImmediateTextNode
|
private let contactSyncNode: ContactSyncNode
|
||||||
|
|
||||||
private let debugAction: () -> Void
|
private let debugAction: () -> Void
|
||||||
|
|
||||||
@ -185,6 +213,16 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var syncContacts: Bool {
|
||||||
|
get {
|
||||||
|
if self.hasOtherAccounts {
|
||||||
|
return self.contactSyncNode.switchNode.isOn
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var selectCountryCode: (() -> Void)?
|
var selectCountryCode: (() -> Void)?
|
||||||
var checkPhone: (() -> Void)?
|
var checkPhone: (() -> Void)?
|
||||||
|
|
||||||
@ -196,10 +234,11 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init(strings: PresentationStrings, theme: PresentationTheme, debugAction: @escaping () -> Void) {
|
init(strings: PresentationStrings, theme: PresentationTheme, debugAction: @escaping () -> Void, hasOtherAccounts: Bool) {
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.debugAction = debugAction
|
self.debugAction = debugAction
|
||||||
|
self.hasOtherAccounts = hasOtherAccounts
|
||||||
|
|
||||||
self.titleNode = ASTextNode()
|
self.titleNode = ASTextNode()
|
||||||
self.titleNode.isUserInteractionEnabled = true
|
self.titleNode.isUserInteractionEnabled = true
|
||||||
@ -211,18 +250,7 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||||||
self.noticeNode.displaysAsynchronously = false
|
self.noticeNode.displaysAsynchronously = false
|
||||||
self.noticeNode.attributedText = NSAttributedString(string: strings.Login_PhoneAndCountryHelp, font: Font.regular(16.0), textColor: theme.list.itemPrimaryTextColor, paragraphAlignment: .center)
|
self.noticeNode.attributedText = NSAttributedString(string: strings.Login_PhoneAndCountryHelp, font: Font.regular(16.0), textColor: theme.list.itemPrimaryTextColor, paragraphAlignment: .center)
|
||||||
|
|
||||||
self.termsOfServiceNode = ImmediateTextNode()
|
self.contactSyncNode = ContactSyncNode(theme: theme, strings: strings)
|
||||||
self.termsOfServiceNode.maximumNumberOfLines = 0
|
|
||||||
self.termsOfServiceNode.textAlignment = .center
|
|
||||||
self.termsOfServiceNode.displaysAsynchronously = false
|
|
||||||
|
|
||||||
let termsOfServiceAttributes = MarkdownAttributeSet(font: Font.regular(16.0), textColor: self.theme.list.itemPrimaryTextColor)
|
|
||||||
let termsOfServiceLinkAttributes = MarkdownAttributeSet(font: Font.regular(16.0), textColor: self.theme.list.itemAccentColor, additionalAttributes: [NSAttributedStringKey.underlineStyle.rawValue: NSUnderlineStyle.styleSingle.rawValue as NSNumber, TelegramTextAttributes.URL: ""])
|
|
||||||
|
|
||||||
let termsString = parseMarkdownIntoAttributedString(self.strings.Login_TermsOfServiceLabel.replacingOccurrences(of: "]", with: "]()"), attributes: MarkdownAttributes(body: termsOfServiceAttributes, bold: termsOfServiceAttributes, link: termsOfServiceLinkAttributes, linkAttribute: { _ in
|
|
||||||
return nil
|
|
||||||
}), textAlignment: .center)
|
|
||||||
self.termsOfServiceNode.attributedText = termsString
|
|
||||||
|
|
||||||
self.phoneAndCountryNode = PhoneAndCountryNode(strings: strings, theme: theme)
|
self.phoneAndCountryNode = PhoneAndCountryNode(strings: strings, theme: theme)
|
||||||
|
|
||||||
@ -235,9 +263,10 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||||||
self.backgroundColor = theme.list.plainBackgroundColor
|
self.backgroundColor = theme.list.plainBackgroundColor
|
||||||
|
|
||||||
self.addSubnode(self.titleNode)
|
self.addSubnode(self.titleNode)
|
||||||
//self.addSubnode(self.termsOfServiceNode)
|
|
||||||
self.addSubnode(self.noticeNode)
|
self.addSubnode(self.noticeNode)
|
||||||
self.addSubnode(self.phoneAndCountryNode)
|
self.addSubnode(self.phoneAndCountryNode)
|
||||||
|
self.addSubnode(self.contactSyncNode)
|
||||||
|
self.contactSyncNode.isHidden = true
|
||||||
|
|
||||||
self.phoneAndCountryNode.selectCountryCode = { [weak self] in
|
self.phoneAndCountryNode.selectCountryCode = { [weak self] in
|
||||||
self?.selectCountryCode?()
|
self?.selectCountryCode?()
|
||||||
@ -245,19 +274,6 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||||||
self.phoneAndCountryNode.checkPhone = { [weak self] in
|
self.phoneAndCountryNode.checkPhone = { [weak self] in
|
||||||
self?.checkPhone?()
|
self?.checkPhone?()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.termsOfServiceNode.highlightAttributeAction = { attributes in
|
|
||||||
if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] {
|
|
||||||
return NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.termsOfServiceNode.tapAttributeAction = { attributes in
|
|
||||||
if let _ = attributes[NSAttributedStringKey(rawValue: TelegramTextAttributes.URL)] as? String {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.termsOfServiceNode.linkHighlightColor = theme.list.itemAccentColor.withAlphaComponent(0.5)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func didLoad() {
|
override func didLoad() {
|
||||||
@ -292,14 +308,15 @@ final class AuthorizationSequencePhoneEntryControllerNode: ASDisplayNode {
|
|||||||
AuthorizationLayoutItem(node: self.noticeNode, size: noticeSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 18.0, maxValue: 18.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)),
|
AuthorizationLayoutItem(node: self.noticeNode, size: noticeSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 18.0, maxValue: 18.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)),
|
||||||
AuthorizationLayoutItem(node: self.phoneAndCountryNode, size: CGSize(width: layout.size.width, height: 115.0), spacingBefore: AuthorizationLayoutItemSpacing(weight: 44.0, maxValue: 44.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0))
|
AuthorizationLayoutItem(node: self.phoneAndCountryNode, size: CGSize(width: layout.size.width, height: 115.0), spacingBefore: AuthorizationLayoutItemSpacing(weight: 44.0, maxValue: 44.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0))
|
||||||
]
|
]
|
||||||
|
let contactSyncSize = self.contactSyncNode.updateLayout(width: layout.size.width)
|
||||||
if layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - 10.0)), items: items, transition: transition, failIfDoesNotFit: true) {
|
if self.hasOtherAccounts {
|
||||||
self.termsOfServiceNode.isHidden = false
|
self.contactSyncNode.isHidden = false
|
||||||
|
items.append(AuthorizationLayoutItem(node: self.contactSyncNode, size: contactSyncSize, spacingBefore: AuthorizationLayoutItemSpacing(weight: 16.0, maxValue: 16.0), spacingAfter: AuthorizationLayoutItemSpacing(weight: 0.0, maxValue: 0.0)))
|
||||||
} else {
|
} else {
|
||||||
items.removeLast()
|
self.contactSyncNode.isHidden = true
|
||||||
let _ = layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - 10.0)), items: items, transition: transition, failIfDoesNotFit: false)
|
|
||||||
self.termsOfServiceNode.isHidden = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _ = layoutAuthorizationItems(bounds: CGRect(origin: CGPoint(x: 0.0, y: insets.top), size: CGSize(width: layout.size.width, height: layout.size.height - insets.top - insets.bottom - 10.0)), items: items, transition: transition, failIfDoesNotFit: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func activateInput() {
|
func activateInput() {
|
||||||
|
|||||||
@ -209,6 +209,7 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
private weak var silentPostTooltipController: TooltipController?
|
private weak var silentPostTooltipController: TooltipController?
|
||||||
private weak var mediaRecordingModeTooltipController: TooltipController?
|
private weak var mediaRecordingModeTooltipController: TooltipController?
|
||||||
private weak var mediaRestrictedTooltipController: TooltipController?
|
private weak var mediaRestrictedTooltipController: TooltipController?
|
||||||
|
private var forwardDisabledNoticeTooltipController: TooltipController?
|
||||||
private var mediaRestrictedTooltipControllerMode = true
|
private var mediaRestrictedTooltipControllerMode = true
|
||||||
|
|
||||||
private var screenCaptureEventsDisposable: Disposable?
|
private var screenCaptureEventsDisposable: Disposable?
|
||||||
@ -1158,6 +1159,24 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
}, cancelInteractiveKeyboardGestures: { [weak self] in
|
}, cancelInteractiveKeyboardGestures: { [weak self] in
|
||||||
(self?.view.window as? WindowHost)?.cancelInteractiveKeyboardGestures()
|
(self?.view.window as? WindowHost)?.cancelInteractiveKeyboardGestures()
|
||||||
self?.chatDisplayNode.cancelInteractiveKeyboardGestures()
|
self?.chatDisplayNode.cancelInteractiveKeyboardGestures()
|
||||||
|
}, displayForwardDisabledNotice: { [weak self] sourceNode, sourceRect, name in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.forwardDisabledNoticeTooltipController?.dismiss()
|
||||||
|
let tooltipController = TooltipController(content: .text(strongSelf.presentationInterfaceState.strings.Chat_ForwardHiddenAccount(name).0), timeout: 2.0, dismissByTapOutside: true)
|
||||||
|
strongSelf.forwardDisabledNoticeTooltipController = tooltipController
|
||||||
|
tooltipController.dismissed = { [weak tooltipController] in
|
||||||
|
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.forwardDisabledNoticeTooltipController === tooltipController {
|
||||||
|
strongSelf.forwardDisabledNoticeTooltipController = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strongSelf.present(tooltipController, in: .window(.root), with: TooltipControllerPresentationArguments(sourceNodeAndRect: {
|
||||||
|
if let strongSelf = self {
|
||||||
|
return (sourceNode, sourceRect)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}))
|
||||||
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,
|
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,
|
||||||
pollActionState: ChatInterfacePollActionState())
|
pollActionState: ChatInterfacePollActionState())
|
||||||
|
|
||||||
|
|||||||
@ -90,6 +90,8 @@ public final class ChatControllerInteraction {
|
|||||||
let requestMessageUpdate: (MessageId) -> Void
|
let requestMessageUpdate: (MessageId) -> Void
|
||||||
let cancelInteractiveKeyboardGestures: () -> Void
|
let cancelInteractiveKeyboardGestures: () -> Void
|
||||||
|
|
||||||
|
let displayForwardDisabledNotice: (ASDisplayNode, CGRect, String) -> Void
|
||||||
|
|
||||||
var hiddenMedia: [MessageId: [Media]] = [:]
|
var hiddenMedia: [MessageId: [Media]] = [:]
|
||||||
var selectionState: ChatInterfaceSelectionState?
|
var selectionState: ChatInterfaceSelectionState?
|
||||||
var highlightedState: ChatInterfaceHighlightedState?
|
var highlightedState: ChatInterfaceHighlightedState?
|
||||||
@ -98,7 +100,7 @@ public final class ChatControllerInteraction {
|
|||||||
var pollActionState: ChatInterfacePollActionState
|
var pollActionState: ChatInterfacePollActionState
|
||||||
var searchTextHighightState: String?
|
var searchTextHighightState: String?
|
||||||
|
|
||||||
init(openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool, openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, Message?) -> Void, openPeerMention: @escaping (String) -> Void, openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect) -> Void, navigateToMessage: @escaping (MessageId, MessageId) -> Void, clickThroughMessage: @escaping () -> Void, toggleMessagesSelection: @escaping ([MessageId], Bool) -> Void, sendMessage: @escaping (String) -> Void, sendSticker: @escaping (FileMediaReference, Bool) -> Void, sendGif: @escaping (FileMediaReference) -> Void, requestMessageActionCallback: @escaping (MessageId, MemoryBuffer?, Bool) -> Void, activateSwitchInline: @escaping (PeerId?, String) -> Void, openUrl: @escaping (String, Bool, Bool?) -> Void, shareCurrentLocation: @escaping () -> Void, shareAccountContact: @escaping () -> Void, sendBotCommand: @escaping (MessageId?, String) -> Void, openInstantPage: @escaping (Message, ChatMessageItemAssociatedData?) -> Void, openWallpaper: @escaping (Message) -> Void, openHashtag: @escaping (String?, String) -> Void, updateInputState: @escaping ((ChatTextInputState) -> ChatTextInputState) -> Void, updateInputMode: @escaping ((ChatInputMode) -> ChatInputMode) -> Void, openMessageShareMenu: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, navigationController: @escaping () -> NavigationController?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, callPeer: @escaping (PeerId) -> Void, longTap: @escaping (ChatControllerInteractionLongTapAction) -> Void, openCheckoutOrReceipt: @escaping (MessageId) -> Void, openSearch: @escaping () -> Void, setupReply: @escaping (MessageId) -> Void, canSetupReply: @escaping (Message) -> Bool, navigateToFirstDateMessage: @escaping(Int32) ->Void, requestRedeliveryOfFailedMessages: @escaping (MessageId) -> Void, addContact: @escaping (String) -> Void, rateCall: @escaping (Message, CallId) -> Void, requestSelectMessagePollOption: @escaping (MessageId, Data) -> Void, openAppStorePage: @escaping () -> Void, requestMessageUpdate: @escaping (MessageId) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, automaticMediaDownloadSettings: MediaAutoDownloadSettings, pollActionState: ChatInterfacePollActionState) {
|
init(openMessage: @escaping (Message, ChatControllerInteractionOpenMessageMode) -> Bool, openPeer: @escaping (PeerId?, ChatControllerInteractionNavigateToPeer, Message?) -> Void, openPeerMention: @escaping (String) -> Void, openMessageContextMenu: @escaping (Message, Bool, ASDisplayNode, CGRect) -> Void, navigateToMessage: @escaping (MessageId, MessageId) -> Void, clickThroughMessage: @escaping () -> Void, toggleMessagesSelection: @escaping ([MessageId], Bool) -> Void, sendMessage: @escaping (String) -> Void, sendSticker: @escaping (FileMediaReference, Bool) -> Void, sendGif: @escaping (FileMediaReference) -> Void, requestMessageActionCallback: @escaping (MessageId, MemoryBuffer?, Bool) -> Void, activateSwitchInline: @escaping (PeerId?, String) -> Void, openUrl: @escaping (String, Bool, Bool?) -> Void, shareCurrentLocation: @escaping () -> Void, shareAccountContact: @escaping () -> Void, sendBotCommand: @escaping (MessageId?, String) -> Void, openInstantPage: @escaping (Message, ChatMessageItemAssociatedData?) -> Void, openWallpaper: @escaping (Message) -> Void, openHashtag: @escaping (String?, String) -> Void, updateInputState: @escaping ((ChatTextInputState) -> ChatTextInputState) -> Void, updateInputMode: @escaping ((ChatInputMode) -> ChatInputMode) -> Void, openMessageShareMenu: @escaping (MessageId) -> Void, presentController: @escaping (ViewController, Any?) -> Void, navigationController: @escaping () -> NavigationController?, presentGlobalOverlayController: @escaping (ViewController, Any?) -> Void, callPeer: @escaping (PeerId) -> Void, longTap: @escaping (ChatControllerInteractionLongTapAction) -> Void, openCheckoutOrReceipt: @escaping (MessageId) -> Void, openSearch: @escaping () -> Void, setupReply: @escaping (MessageId) -> Void, canSetupReply: @escaping (Message) -> Bool, navigateToFirstDateMessage: @escaping(Int32) ->Void, requestRedeliveryOfFailedMessages: @escaping (MessageId) -> Void, addContact: @escaping (String) -> Void, rateCall: @escaping (Message, CallId) -> Void, requestSelectMessagePollOption: @escaping (MessageId, Data) -> Void, openAppStorePage: @escaping () -> Void, requestMessageUpdate: @escaping (MessageId) -> Void, cancelInteractiveKeyboardGestures: @escaping () -> Void, displayForwardDisabledNotice: @escaping (ASDisplayNode, CGRect, String) -> Void, automaticMediaDownloadSettings: MediaAutoDownloadSettings, pollActionState: ChatInterfacePollActionState) {
|
||||||
self.openMessage = openMessage
|
self.openMessage = openMessage
|
||||||
self.openPeer = openPeer
|
self.openPeer = openPeer
|
||||||
self.openPeerMention = openPeerMention
|
self.openPeerMention = openPeerMention
|
||||||
@ -139,6 +141,7 @@ public final class ChatControllerInteraction {
|
|||||||
|
|
||||||
self.requestMessageUpdate = requestMessageUpdate
|
self.requestMessageUpdate = requestMessageUpdate
|
||||||
self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures
|
self.cancelInteractiveKeyboardGestures = cancelInteractiveKeyboardGestures
|
||||||
|
self.displayForwardDisabledNotice = displayForwardDisabledNotice
|
||||||
|
|
||||||
self.automaticMediaDownloadSettings = automaticMediaDownloadSettings
|
self.automaticMediaDownloadSettings = automaticMediaDownloadSettings
|
||||||
|
|
||||||
@ -161,7 +164,7 @@ public final class ChatControllerInteraction {
|
|||||||
}, openAppStorePage: {
|
}, openAppStorePage: {
|
||||||
}, requestMessageUpdate: { _ in
|
}, requestMessageUpdate: { _ in
|
||||||
}, cancelInteractiveKeyboardGestures: {
|
}, cancelInteractiveKeyboardGestures: {
|
||||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
}, displayForwardDisabledNotice: { _, _, _ in }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||||
pollActionState: ChatInterfacePollActionState())
|
pollActionState: ChatInterfacePollActionState())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1597,6 +1597,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
|||||||
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
|
item.controllerInteraction.navigateToMessage(item.message.id, sourceMessageId)
|
||||||
} else if let id = forwardInfo.source?.id ?? forwardInfo.author?.id {
|
} else if let id = forwardInfo.source?.id ?? forwardInfo.author?.id {
|
||||||
item.controllerInteraction.openPeer(id, .info, nil)
|
item.controllerInteraction.openPeer(id, .info, nil)
|
||||||
|
} else if let authorSignature = forwardInfo.authorSignature {
|
||||||
|
item.controllerInteraction.displayForwardDisabledNotice(forwardInfoNode, forwardInfoNode.bounds, authorSignature)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -364,7 +364,7 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
}, requestMessageUpdate: { _ in
|
}, requestMessageUpdate: { _ in
|
||||||
}, cancelInteractiveKeyboardGestures: {
|
}, cancelInteractiveKeyboardGestures: {
|
||||||
}, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,
|
}, displayForwardDisabledNotice: { _, _, _ in }, automaticMediaDownloadSettings: self.automaticMediaDownloadSettings,
|
||||||
pollActionState: ChatInterfacePollActionState())
|
pollActionState: ChatInterfacePollActionState())
|
||||||
self.controllerInteraction = controllerInteraction
|
self.controllerInteraction = controllerInteraction
|
||||||
|
|
||||||
|
|||||||
@ -819,9 +819,10 @@ final class ContactListNode: ASDisplayNode {
|
|||||||
let contactsWarningSuppressed = Promise<(Bool, Bool)>()
|
let contactsWarningSuppressed = Promise<(Bool, Bool)>()
|
||||||
contactsWarningSuppressed.set(.single((false, false))
|
contactsWarningSuppressed.set(.single((false, false))
|
||||||
|> then(
|
|> then(
|
||||||
combineLatest(context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.contactsPermissionWarningKey()), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]))
|
combineLatest(context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.contactsPermissionWarningKey()), context.account.postbox.preferencesView(keys: [PreferencesKeys.contactsSettings]))
|
||||||
|> map { noticeView, sharedData -> (Bool, Bool) in
|
|> map { noticeView, preferences -> (Bool, Bool) in
|
||||||
let synchronizeDeviceContacts: Bool = (sharedData.entries[ApplicationSpecificSharedDataKeys.contactSynchronizationSettings] as? ContactSynchronizationSettings)?.synchronizeDeviceContacts ?? true
|
let settings: ContactsSettings = preferences.values[PreferencesKeys.contactsSettings] as? ContactsSettings ?? ContactsSettings.defaultSettings
|
||||||
|
let synchronizeDeviceContacts: Bool = settings.synchronizeContacts
|
||||||
let suppressed: Bool
|
let suppressed: Bool
|
||||||
let timestamp = noticeView.value.flatMap({ ApplicationSpecificNotice.getTimestampValue($0) })
|
let timestamp = noticeView.value.flatMap({ ApplicationSpecificNotice.getTimestampValue($0) })
|
||||||
if let timestamp = timestamp, timestamp > 0 {
|
if let timestamp = timestamp, timestamp > 0 {
|
||||||
|
|||||||
@ -8,28 +8,28 @@ public enum ContactsSortOrder: Int32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public struct ContactSynchronizationSettings: Equatable, PreferencesEntry {
|
public struct ContactSynchronizationSettings: Equatable, PreferencesEntry {
|
||||||
public var synchronizeDeviceContacts: Bool
|
public var _legacySynchronizeDeviceContacts: Bool
|
||||||
public var nameDisplayOrder: PresentationPersonNameOrder
|
public var nameDisplayOrder: PresentationPersonNameOrder
|
||||||
public var sortOrder: ContactsSortOrder
|
public var sortOrder: ContactsSortOrder
|
||||||
|
|
||||||
public static var defaultSettings: ContactSynchronizationSettings {
|
public static var defaultSettings: ContactSynchronizationSettings {
|
||||||
return ContactSynchronizationSettings(synchronizeDeviceContacts: true, nameDisplayOrder: .firstLast, sortOrder: .presence)
|
return ContactSynchronizationSettings(_legacySynchronizeDeviceContacts: true, nameDisplayOrder: .firstLast, sortOrder: .presence)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(synchronizeDeviceContacts: Bool, nameDisplayOrder: PresentationPersonNameOrder, sortOrder: ContactsSortOrder) {
|
public init(_legacySynchronizeDeviceContacts: Bool, nameDisplayOrder: PresentationPersonNameOrder, sortOrder: ContactsSortOrder) {
|
||||||
self.synchronizeDeviceContacts = synchronizeDeviceContacts
|
self._legacySynchronizeDeviceContacts = _legacySynchronizeDeviceContacts
|
||||||
self.nameDisplayOrder = nameDisplayOrder
|
self.nameDisplayOrder = nameDisplayOrder
|
||||||
self.sortOrder = sortOrder
|
self.sortOrder = sortOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
self.synchronizeDeviceContacts = decoder.decodeInt32ForKey("synchronizeDeviceContacts", orElse: 0) != 0
|
self._legacySynchronizeDeviceContacts = decoder.decodeInt32ForKey("synchronizeDeviceContacts", orElse: 0) != 0
|
||||||
self.nameDisplayOrder = PresentationPersonNameOrder(rawValue: decoder.decodeInt32ForKey("nameDisplayOrder", orElse: 0)) ?? .firstLast
|
self.nameDisplayOrder = PresentationPersonNameOrder(rawValue: decoder.decodeInt32ForKey("nameDisplayOrder", orElse: 0)) ?? .firstLast
|
||||||
self.sortOrder = ContactsSortOrder(rawValue: decoder.decodeInt32ForKey("sortOrder", orElse: 0)) ?? .presence
|
self.sortOrder = ContactsSortOrder(rawValue: decoder.decodeInt32ForKey("sortOrder", orElse: 0)) ?? .presence
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
encoder.encodeInt32(self.synchronizeDeviceContacts ? 1 : 0, forKey: "synchronizeDeviceContacts")
|
encoder.encodeInt32(self._legacySynchronizeDeviceContacts ? 1 : 0, forKey: "synchronizeDeviceContacts")
|
||||||
encoder.encodeInt32(self.nameDisplayOrder.rawValue, forKey: "nameDisplayOrder")
|
encoder.encodeInt32(self.nameDisplayOrder.rawValue, forKey: "nameDisplayOrder")
|
||||||
encoder.encodeInt32(self.sortOrder.rawValue, forKey: "sortOrder")
|
encoder.encodeInt32(self.sortOrder.rawValue, forKey: "sortOrder")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -119,11 +119,14 @@ public class ContactsController: ViewController {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if #available(iOSApplicationExtension 10.0, *) {
|
if #available(iOSApplicationExtension 10.0, *) {
|
||||||
self.authorizationDisposable = (combineLatest(DeviceAccess.authorizationStatus(context: context, subject: .contacts), combineLatest(context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.contactsPermissionWarningKey()), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]))
|
self.authorizationDisposable = (combineLatest(DeviceAccess.authorizationStatus(context: context, subject: .contacts), combineLatest(context.sharedContext.accountManager.noticeEntry(key: ApplicationSpecificNotice.contactsPermissionWarningKey()), context.account.postbox.preferencesView(keys: [PreferencesKeys.contactsSettings]), context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.contactSynchronizationSettings]))
|
||||||
|> map { noticeView, sharedData -> (Bool, ContactsSortOrder) in
|
|> map { noticeView, preferences, sharedData -> (Bool, ContactsSortOrder) in
|
||||||
let settings = sharedData.entries[ApplicationSpecificSharedDataKeys.contactSynchronizationSettings] as? ContactSynchronizationSettings
|
let settings: ContactsSettings = preferences.values[PreferencesKeys.contactsSettings] as? ContactsSettings ?? ContactsSettings.defaultSettings
|
||||||
let synchronizeDeviceContacts: Bool = settings?.synchronizeDeviceContacts ?? true
|
let synchronizeDeviceContacts: Bool = settings.synchronizeContacts
|
||||||
let sortOrder: ContactsSortOrder = settings?.sortOrder ?? .presence
|
|
||||||
|
let contactsSettings = sharedData.entries[ApplicationSpecificSharedDataKeys.contactSynchronizationSettings] as? ContactSynchronizationSettings
|
||||||
|
|
||||||
|
let sortOrder: ContactsSortOrder = contactsSettings?.sortOrder ?? .presence
|
||||||
if !synchronizeDeviceContacts {
|
if !synchronizeDeviceContacts {
|
||||||
return (true, sortOrder)
|
return (true, sortOrder)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -394,11 +394,13 @@ public func dataPrivacyController(context: AccountContext) -> ViewController {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = updateContactSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
let _ = context.account.postbox.transaction({ transaction in
|
||||||
var settings = settings
|
transaction.updatePreferencesEntry(key: PreferencesKeys.contactsSettings, { current in
|
||||||
settings.synchronizeDeviceContacts = false
|
var settings = current as? ContactsSettings ?? ContactsSettings.defaultSettings
|
||||||
return settings
|
settings.synchronizeContacts = false
|
||||||
})
|
return settings
|
||||||
|
})
|
||||||
|
}).start()
|
||||||
|
|
||||||
actionsDisposable.add(((deleteAllContacts(postbox: context.account.postbox, network: context.account.network) |> then(resetSavedContacts(network: context.account.network)))
|
actionsDisposable.add(((deleteAllContacts(postbox: context.account.postbox, network: context.account.network) |> then(resetSavedContacts(network: context.account.network)))
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
@ -413,10 +415,12 @@ public func dataPrivacyController(context: AccountContext) -> ViewController {
|
|||||||
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {})]))
|
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {})]))
|
||||||
}
|
}
|
||||||
}, updateSyncContacts: { value in
|
}, updateSyncContacts: { value in
|
||||||
let _ = updateContactSettingsInteractively(accountManager: context.sharedContext.accountManager, { settings in
|
let _ = context.account.postbox.transaction({ transaction in
|
||||||
var settings = settings
|
transaction.updatePreferencesEntry(key: PreferencesKeys.contactsSettings, { current in
|
||||||
settings.synchronizeDeviceContacts = value
|
var settings = current as? ContactsSettings ?? ContactsSettings.defaultSettings
|
||||||
return settings
|
settings.synchronizeContacts = value
|
||||||
|
return settings
|
||||||
|
})
|
||||||
}).start()
|
}).start()
|
||||||
}, updateSuggestFrequentContacts: { value in
|
}, updateSuggestFrequentContacts: { value in
|
||||||
let apply: () -> Void = {
|
let apply: () -> Void = {
|
||||||
@ -477,11 +481,13 @@ public func dataPrivacyController(context: AccountContext) -> ViewController {
|
|||||||
|
|
||||||
actionsDisposable.add(managedUpdatedRecentPeers(accountPeerId: context.account.peerId, postbox: context.account.postbox, network: context.account.network).start())
|
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]), recentPeers(account: context.account))
|
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, recentPeers -> (ItemListControllerState, (ItemListNodeState<PrivacyAndSecurityEntry>, PrivacyAndSecurityEntry.ItemGenerationArguments)) in
|
|> map { presentationData, state, noticeView, sharedData, preferences, recentPeers -> (ItemListControllerState, (ItemListNodeState<PrivacyAndSecurityEntry>, PrivacyAndSecurityEntry.ItemGenerationArguments)) in
|
||||||
let secretChatLinkPreviews = noticeView.value.flatMap({ ApplicationSpecificNotice.getSecretChatLinkPreviews($0) })
|
let secretChatLinkPreviews = noticeView.value.flatMap({ ApplicationSpecificNotice.getSecretChatLinkPreviews($0) })
|
||||||
|
|
||||||
let synchronizeDeviceContacts: Bool = (sharedData.entries[ApplicationSpecificSharedDataKeys.contactSynchronizationSettings] as? ContactSynchronizationSettings)?.synchronizeDeviceContacts ?? true
|
let settings: ContactsSettings = preferences.values[PreferencesKeys.contactsSettings] as? ContactsSettings ?? ContactsSettings.defaultSettings
|
||||||
|
|
||||||
|
let synchronizeDeviceContacts: Bool = settings.synchronizeContacts
|
||||||
|
|
||||||
let suggestRecentPeers: Bool
|
let suggestRecentPeers: Bool
|
||||||
if let updatedSuggestFrequentContacts = state.updatedSuggestFrequentContacts {
|
if let updatedSuggestFrequentContacts = state.updatedSuggestFrequentContacts {
|
||||||
|
|||||||
@ -73,7 +73,7 @@ final class OverlayPlayerControllerNode: ViewControllerTracingNode, UIGestureRec
|
|||||||
}, openAppStorePage: {
|
}, openAppStorePage: {
|
||||||
}, requestMessageUpdate: { _ in
|
}, requestMessageUpdate: { _ in
|
||||||
}, cancelInteractiveKeyboardGestures: {
|
}, cancelInteractiveKeyboardGestures: {
|
||||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
}, displayForwardDisabledNotice: { _, _, _ in }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||||
pollActionState: ChatInterfacePollActionState())
|
pollActionState: ChatInterfacePollActionState())
|
||||||
|
|
||||||
self.dimNode = ASDisplayNode()
|
self.dimNode = ASDisplayNode()
|
||||||
|
|||||||
@ -255,7 +255,7 @@ public class PeerMediaCollectionController: TelegramController {
|
|||||||
}, openAppStorePage: {
|
}, openAppStorePage: {
|
||||||
}, requestMessageUpdate: { _ in
|
}, requestMessageUpdate: { _ in
|
||||||
}, cancelInteractiveKeyboardGestures: {
|
}, cancelInteractiveKeyboardGestures: {
|
||||||
}, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
}, displayForwardDisabledNotice: { _, _, _ in }, automaticMediaDownloadSettings: MediaAutoDownloadSettings.defaultSettings,
|
||||||
pollActionState: ChatInterfacePollActionState())
|
pollActionState: ChatInterfacePollActionState())
|
||||||
|
|
||||||
self.controllerInteraction = controllerInteraction
|
self.controllerInteraction = controllerInteraction
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -241,6 +241,37 @@ public func upgradedAccounts(accountManager: AccountManager, rootPath: String) -
|
|||||||
signal = signal |> then(upgradeAccessChallengeData)
|
signal = signal |> then(upgradeAccessChallengeData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if version < 4 {
|
||||||
|
let updatedContactSynchronizationSettings = accountManager.transaction { transaction -> (ContactSynchronizationSettings, [AccountRecordId]) in
|
||||||
|
return (transaction.getSharedData(ApplicationSpecificSharedDataKeys.contactSynchronizationSettings) as? ContactSynchronizationSettings ?? ContactSynchronizationSettings.defaultSettings, transaction.getRecords().map({ $0.id }))
|
||||||
|
}
|
||||||
|
|> mapToSignal { globalSettings, ids -> Signal<Never, NoError> in
|
||||||
|
var importSignal: Signal<Never, NoError> = .complete()
|
||||||
|
for id in ids {
|
||||||
|
let importInfoAccounttSignal = accountTransaction(rootPath: rootPath, id: id, transaction: { transaction -> Void in
|
||||||
|
transaction.updatePreferencesEntry(key: PreferencesKeys.contactsSettings, { current in
|
||||||
|
var settings = current as? ContactsSettings ?? ContactsSettings.defaultSettings
|
||||||
|
settings.synchronizeContacts = globalSettings._legacySynchronizeDeviceContacts
|
||||||
|
return settings
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|> ignoreValues
|
||||||
|
importSignal = importSignal |> then(importInfoAccounttSignal)
|
||||||
|
}
|
||||||
|
return importSignal
|
||||||
|
}
|
||||||
|
|
||||||
|
let applyVersion = accountManager.transaction { transaction -> Void in
|
||||||
|
transaction.setVersion(4)
|
||||||
|
}
|
||||||
|
|> ignoreValues
|
||||||
|
signal = signal |> then(
|
||||||
|
updatedContactSynchronizationSettings
|
||||||
|
|> then(
|
||||||
|
applyVersion
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
return signal
|
return signal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user