Merge commit '20ed214511767450e92fe92bb2b2aa1aa86bbe0a'

This commit is contained in:
Peter
2019-08-28 12:27:52 +04:00
3 changed files with 344 additions and 316 deletions

View File

@@ -1329,7 +1329,6 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
if let currentMutedIconImage = currentMutedIconImage {
strongSelf.mutedIconNode.image = currentMutedIconImage
strongSelf.mutedIconNode.isHidden = false
transition.updateFrame(node: strongSelf.mutedIconNode, frame: CGRect(origin: CGPoint(x: nextTitleIconOrigin - 4.0, y: contentRect.origin.y - 2.0), size: currentMutedIconImage.size))
nextTitleIconOrigin += currentMutedIconImage.size.width + 1.0
} else {
@@ -1568,7 +1567,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
}
let mutedIconFrame = self.mutedIconNode.frame
transition.updateFrame(node: self.mutedIconNode, frame: CGRect(origin: CGPoint(x: nextTitleIconOrigin - 6.0, y: contentRect.origin.y - 1.0), size: mutedIconFrame.size))
transition.updateFrame(node: self.mutedIconNode, frame: CGRect(origin: CGPoint(x: nextTitleIconOrigin - 4.0, y: contentRect.origin.y - 2.0), size: mutedIconFrame.size))
nextTitleIconOrigin += mutedIconFrame.size.width + 3.0
let badgeFrame = self.badgeNode.frame

View File

@@ -16,16 +16,24 @@ import ItemListUI
import OverlayStatusController
import AccountContext
@objc private final class DebugControllerMailComposeDelegate: NSObject, MFMailComposeViewControllerDelegate {
public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
controller.dismiss(animated: true, completion: nil)
}
}
private final class DebugControllerArguments {
let sharedContext: SharedAccountContext
let context: AccountContext?
let mailComposeDelegate: DebugControllerMailComposeDelegate
let presentController: (ViewController, ViewControllerPresentationArguments?) -> Void
let pushController: (ViewController) -> Void
let getRootController: () -> UIViewController?
init(sharedContext: SharedAccountContext, context: AccountContext?, presentController: @escaping (ViewController, ViewControllerPresentationArguments?) -> Void, pushController: @escaping (ViewController) -> Void, getRootController: @escaping () -> UIViewController?) {
init(sharedContext: SharedAccountContext, context: AccountContext?, mailComposeDelegate: DebugControllerMailComposeDelegate, presentController: @escaping (ViewController, ViewControllerPresentationArguments?) -> Void, pushController: @escaping (ViewController) -> Void, getRootController: @escaping () -> UIViewController?) {
self.sharedContext = sharedContext
self.context = context
self.mailComposeDelegate = mailComposeDelegate
self.presentController = presentController
self.pushController = pushController
self.getRootController = getRootController
@@ -57,6 +65,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
case resetData(PresentationTheme)
case resetDatabase(PresentationTheme)
case resetHoles(PresentationTheme)
case resetBiometricsData(PresentationTheme)
case optimizeDatabase(PresentationTheme)
case photoPreview(PresentationTheme, Bool)
case knockoutWallpaper(PresentationTheme, Bool)
@@ -64,65 +73,67 @@ private enum DebugControllerEntry: ItemListNodeEntry {
var section: ItemListSectionId {
switch self {
case .sendLogs, .sendOneLog, .sendNotificationLogs, .sendCriticalLogs:
return DebugControllerSection.logs.rawValue
case .accounts:
return DebugControllerSection.logs.rawValue
case .logToFile, .logToConsole, .redactSensitiveData:
return DebugControllerSection.logging.rawValue
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
return DebugControllerSection.experiments.rawValue
case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .optimizeDatabase, .photoPreview, .knockoutWallpaper:
return DebugControllerSection.experiments.rawValue
case .versionInfo:
return DebugControllerSection.info.rawValue
case .sendLogs, .sendOneLog, .sendNotificationLogs, .sendCriticalLogs:
return DebugControllerSection.logs.rawValue
case .accounts:
return DebugControllerSection.logs.rawValue
case .logToFile, .logToConsole, .redactSensitiveData:
return DebugControllerSection.logging.rawValue
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
return DebugControllerSection.experiments.rawValue
case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .knockoutWallpaper:
return DebugControllerSection.experiments.rawValue
case .versionInfo:
return DebugControllerSection.info.rawValue
}
}
var stableId: Int32 {
switch self {
case .sendLogs:
return 0
case .sendOneLog:
return 1
case .sendNotificationLogs:
return 2
case .sendCriticalLogs:
return 3
case .accounts:
return 4
case .logToFile:
return 5
case .logToConsole:
return 6
case .redactSensitiveData:
return 7
case .enableRaiseToSpeak:
return 8
case .keepChatNavigationStack:
return 9
case .skipReadHistory:
return 10
case .crashOnSlowQueries:
return 11
case .clearTips:
return 12
case .reimport:
return 13
case .resetData:
return 14
case .resetDatabase:
return 15
case .resetHoles:
return 16
case .optimizeDatabase:
return 17
case .photoPreview:
return 18
case .knockoutWallpaper:
return 19
case .versionInfo:
return 20
case .sendLogs:
return 0
case .sendOneLog:
return 1
case .sendNotificationLogs:
return 2
case .sendCriticalLogs:
return 3
case .accounts:
return 4
case .logToFile:
return 5
case .logToConsole:
return 6
case .redactSensitiveData:
return 7
case .enableRaiseToSpeak:
return 8
case .keepChatNavigationStack:
return 9
case .skipReadHistory:
return 10
case .crashOnSlowQueries:
return 11
case .clearTips:
return 12
case .reimport:
return 13
case .resetData:
return 14
case .resetDatabase:
return 15
case .resetHoles:
return 16
case .resetBiometricsData:
return 17
case .optimizeDatabase:
return 18
case .photoPreview:
return 19
case .knockoutWallpaper:
return 20
case .versionInfo:
return 21
}
}
@@ -132,9 +143,9 @@ private enum DebugControllerEntry: ItemListNodeEntry {
func item(_ arguments: DebugControllerArguments) -> ListViewItem {
switch self {
case let .sendLogs(theme):
return ItemListDisclosureItem(theme: theme, title: "Send Logs", label: "", sectionId: self.section, style: .blocks, action: {
let _ = (Logger.shared.collectLogs()
case let .sendLogs(theme):
return ItemListDisclosureItem(theme: theme, title: "Send Logs", label: "", sectionId: self.section, style: .blocks, action: {
let _ = (Logger.shared.collectLogs()
|> deliverOnMainQueue).start(next: { logs in
guard let context = arguments.context else {
return
@@ -142,8 +153,11 @@ private enum DebugControllerEntry: ItemListNodeEntry {
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: "Via Telegram", color: .accent, action: { [weak actionSheet] in
var items: [ActionSheetButtonItem] = []
if let context = arguments.context {
items.append(ActionSheetButtonItem(title: "Via Telegram", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyWriteable, .excludeDisabled]))
@@ -160,39 +174,41 @@ private enum DebugControllerEntry: ItemListNodeEntry {
}
}
arguments.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet))
}),
ActionSheetButtonItem(title: "Via Email", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let composeController = MFMailComposeViewController()
composeController.setSubject("Telegram Logs")
for (name, path) in logs {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) {
composeController.addAttachmentData(data, mimeType: "application/text", fileName: name)
}
}))
}
items.append(ActionSheetButtonItem(title: "Via Email", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let composeController = MFMailComposeViewController()
composeController.mailComposeDelegate = arguments.mailComposeDelegate
composeController.setSubject("Telegram Logs")
for (name, path) in logs {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) {
composeController.addAttachmentData(data, mimeType: "application/text", fileName: name)
}
arguments.getRootController()?.present(composeController, animated: true, completion: nil)
})
]), ActionSheetItemGroup(items: [
}
arguments.getRootController()?.present(composeController, animated: true, completion: nil)
}))
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
])])
arguments.presentController(actionSheet, nil)
})
})
case let .sendOneLog(theme):
return ItemListDisclosureItem(theme: theme, title: "Send Latest Log", label: "", sectionId: self.section, style: .blocks, action: {
let _ = (Logger.shared.collectLogs()
})
case let .sendOneLog(theme):
return ItemListDisclosureItem(theme: theme, title: "Send Latest Log", label: "", sectionId: self.section, style: .blocks, action: {
let _ = (Logger.shared.collectLogs()
|> deliverOnMainQueue).start(next: { logs in
guard let context = arguments.context else {
return
}
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: "Via Telegram", color: .accent, action: { [weak actionSheet] in
var items: [ActionSheetButtonItem] = []
if let context = arguments.context {
items.append(ActionSheetButtonItem(title: "Via Telegram", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyWriteable, .excludeDisabled]))
@@ -211,31 +227,35 @@ private enum DebugControllerEntry: ItemListNodeEntry {
}
}
arguments.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet))
}),
ActionSheetButtonItem(title: "Via Email", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let composeController = MFMailComposeViewController()
composeController.setSubject("Telegram Logs")
for (name, path) in logs {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) {
composeController.addAttachmentData(data, mimeType: "application/text", fileName: name)
}
}))
}
items.append(ActionSheetButtonItem(title: "Via Email", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let composeController = MFMailComposeViewController()
composeController.mailComposeDelegate = arguments.mailComposeDelegate
composeController.setSubject("Telegram Logs")
for (name, path) in logs {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) {
composeController.addAttachmentData(data, mimeType: "application/text", fileName: name)
}
arguments.getRootController()?.present(composeController, animated: true, completion: nil)
}
arguments.getRootController()?.present(composeController, animated: true, completion: nil)
}))
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
]), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])
])
])
arguments.presentController(actionSheet, nil)
})
})
case let .sendNotificationLogs(theme):
return ItemListDisclosureItem(theme: theme, title: "Send Notification Logs", label: "", sectionId: self.section, style: .blocks, action: {
let _ = (Logger(basePath: arguments.sharedContext.basePath + "/notificationServiceLogs").collectLogs()
})
case let .sendNotificationLogs(theme):
return ItemListDisclosureItem(theme: theme, title: "Send Notification Logs", label: "", sectionId: self.section, style: .blocks, action: {
let _ = (Logger(basePath: arguments.sharedContext.basePath + "/notificationServiceLogs").collectLogs()
|> deliverOnMainQueue).start(next: { logs in
guard let context = arguments.context else {
return
@@ -255,19 +275,18 @@ private enum DebugControllerEntry: ItemListNodeEntry {
}
arguments.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet))
})
})
case let .sendCriticalLogs(theme):
return ItemListDisclosureItem(theme: theme, title: "Send Critical Logs", label: "", sectionId: self.section, style: .blocks, action: {
let _ = (Logger.shared.collectShortLogFiles()
})
case let .sendCriticalLogs(theme):
return ItemListDisclosureItem(theme: theme, title: "Send Critical Logs", label: "", sectionId: self.section, style: .blocks, action: {
let _ = (Logger.shared.collectShortLogFiles()
|> deliverOnMainQueue).start(next: { logs in
guard let context = arguments.context else {
return
}
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: "Via Telegram", color: .accent, action: { [weak actionSheet] in
var items: [ActionSheetButtonItem] = []
if let context = arguments.context {
items.append(ActionSheetButtonItem(title: "Via Telegram", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyWriteable, .excludeDisabled]))
@@ -284,201 +303,210 @@ private enum DebugControllerEntry: ItemListNodeEntry {
}
}
arguments.presentController(controller, ViewControllerPresentationArguments(presentationAnimation: ViewControllerPresentationAnimation.modalSheet))
}),
ActionSheetButtonItem(title: "Via Email", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let composeController = MFMailComposeViewController()
composeController.setSubject("Telegram Logs")
for (name, path) in logs {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) {
composeController.addAttachmentData(data, mimeType: "application/text", fileName: name)
}
}))
}
items.append(ActionSheetButtonItem(title: "Via Email", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let composeController = MFMailComposeViewController()
composeController.mailComposeDelegate = arguments.mailComposeDelegate
composeController.setSubject("Telegram Logs")
for (name, path) in logs {
if let data = try? Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe) {
composeController.addAttachmentData(data, mimeType: "application/text", fileName: name)
}
arguments.getRootController()?.present(composeController, animated: true, completion: nil)
})
]), ActionSheetItemGroup(items: [
}
arguments.getRootController()?.present(composeController, animated: true, completion: nil)
}))
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
])])
arguments.presentController(actionSheet, nil)
})
})
case let .accounts(theme):
return ItemListDisclosureItem(theme: theme, title: "Accounts", label: "", sectionId: self.section, style: .blocks, action: {
guard let context = arguments.context else {
return
}
arguments.pushController(debugAccountsController(context: context, accountManager: arguments.sharedContext.accountManager))
})
case let .logToFile(theme, value):
return ItemListSwitchItem(theme: theme, title: "Log to File", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateLoggingSettings(accountManager: arguments.sharedContext.accountManager, {
$0.withUpdatedLogToFile(value)
}).start()
})
case let .logToConsole(theme, value):
return ItemListSwitchItem(theme: theme, title: "Log to Console", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateLoggingSettings(accountManager: arguments.sharedContext.accountManager, {
$0.withUpdatedLogToConsole(value)
}).start()
})
case let .redactSensitiveData(theme, value):
return ItemListSwitchItem(theme: theme, title: "Remove Sensitive Data", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateLoggingSettings(accountManager: arguments.sharedContext.accountManager, {
$0.withUpdatedRedactSensitiveData(value)
}).start()
})
case let .enableRaiseToSpeak(theme, value):
return ItemListSwitchItem(theme: theme, title: "Enable Raise to Speak", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateMediaInputSettingsInteractively(accountManager: arguments.sharedContext.accountManager, {
$0.withUpdatedEnableRaiseToSpeak(value)
}).start()
})
case let .keepChatNavigationStack(theme, value):
return ItemListSwitchItem(theme: theme, title: "Keep Chat Stack", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateExperimentalUISettingsInteractively(accountManager: arguments.sharedContext.accountManager, { settings in
var settings = settings
settings.keepChatNavigationStack = value
return settings
}).start()
})
case let .skipReadHistory(theme, value):
return ItemListSwitchItem(theme: theme, title: "Skip read history", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateExperimentalUISettingsInteractively(accountManager: arguments.sharedContext.accountManager, { settings in
var settings = settings
settings.skipReadHistory = value
return settings
}).start()
})
case let .crashOnSlowQueries(theme, value):
return ItemListSwitchItem(theme: theme, title: "Crash when slow", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateExperimentalUISettingsInteractively(accountManager: arguments.sharedContext.accountManager, { settings in
var settings = settings
settings.crashOnLongQueries = value
return settings
}).start()
})
case let .clearTips(theme):
return ItemListActionItem(theme: theme, title: "Clear Tips", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
let _ = (arguments.sharedContext.accountManager.transaction { transaction -> Void in
transaction.clearNotices()
}).start()
})
case let .reimport(theme):
return ItemListActionItem(theme: theme, title: "Reimport Application Data", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
let appGroupName = "group.\(Bundle.main.bundleIdentifier!)"
let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName)
guard let appGroupUrl = maybeAppGroupUrl else {
return
}
let statusPath = appGroupUrl.path + "/Documents/importcompleted"
if FileManager.default.fileExists(atPath: statusPath) {
let _ = try? FileManager.default.removeItem(at: URL(fileURLWithPath: statusPath))
exit(0)
}
})
case let .resetData(theme):
return ItemListActionItem(theme: theme, title: "Reset Data", kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: {
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: "All data will be lost."),
ActionSheetButtonItem(title: "Reset Data", color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let databasePath = arguments.sharedContext.accountManager.basePath + "/db"
let _ = try? FileManager.default.removeItem(atPath: databasePath)
preconditionFailure()
}),
})
case let .accounts(theme):
return ItemListDisclosureItem(theme: theme, title: "Accounts", label: "", sectionId: self.section, style: .blocks, action: {
guard let context = arguments.context else {
return
}
arguments.pushController(debugAccountsController(context: context, accountManager: arguments.sharedContext.accountManager))
})
case let .logToFile(theme, value):
return ItemListSwitchItem(theme: theme, title: "Log to File", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateLoggingSettings(accountManager: arguments.sharedContext.accountManager, {
$0.withUpdatedLogToFile(value)
}).start()
})
case let .logToConsole(theme, value):
return ItemListSwitchItem(theme: theme, title: "Log to Console", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateLoggingSettings(accountManager: arguments.sharedContext.accountManager, {
$0.withUpdatedLogToConsole(value)
}).start()
})
case let .redactSensitiveData(theme, value):
return ItemListSwitchItem(theme: theme, title: "Remove Sensitive Data", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateLoggingSettings(accountManager: arguments.sharedContext.accountManager, {
$0.withUpdatedRedactSensitiveData(value)
}).start()
})
case let .enableRaiseToSpeak(theme, value):
return ItemListSwitchItem(theme: theme, title: "Enable Raise to Speak", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateMediaInputSettingsInteractively(accountManager: arguments.sharedContext.accountManager, {
$0.withUpdatedEnableRaiseToSpeak(value)
}).start()
})
case let .keepChatNavigationStack(theme, value):
return ItemListSwitchItem(theme: theme, title: "Keep Chat Stack", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateExperimentalUISettingsInteractively(accountManager: arguments.sharedContext.accountManager, { settings in
var settings = settings
settings.keepChatNavigationStack = value
return settings
}).start()
})
case let .skipReadHistory(theme, value):
return ItemListSwitchItem(theme: theme, title: "Skip read history", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateExperimentalUISettingsInteractively(accountManager: arguments.sharedContext.accountManager, { settings in
var settings = settings
settings.skipReadHistory = value
return settings
}).start()
})
case let .crashOnSlowQueries(theme, value):
return ItemListSwitchItem(theme: theme, title: "Crash when slow", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = updateExperimentalUISettingsInteractively(accountManager: arguments.sharedContext.accountManager, { settings in
var settings = settings
settings.crashOnLongQueries = value
return settings
}).start()
})
case let .clearTips(theme):
return ItemListActionItem(theme: theme, title: "Clear Tips", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
let _ = (arguments.sharedContext.accountManager.transaction { transaction -> Void in
transaction.clearNotices()
}).start()
})
case let .reimport(theme):
return ItemListActionItem(theme: theme, title: "Reimport Application Data", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
let appGroupName = "group.\(Bundle.main.bundleIdentifier!)"
let maybeAppGroupUrl = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupName)
guard let appGroupUrl = maybeAppGroupUrl else {
return
}
let statusPath = appGroupUrl.path + "/Documents/importcompleted"
if FileManager.default.fileExists(atPath: statusPath) {
let _ = try? FileManager.default.removeItem(at: URL(fileURLWithPath: statusPath))
exit(0)
}
})
case let .resetData(theme):
return ItemListActionItem(theme: theme, title: "Reset Data", kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: {
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: "All data will be lost."),
ActionSheetButtonItem(title: "Reset Data", color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let databasePath = arguments.sharedContext.accountManager.basePath + "/db"
let _ = try? FileManager.default.removeItem(atPath: databasePath)
preconditionFailure()
}),
]), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
arguments.presentController(actionSheet, nil)
})
case let .resetDatabase(theme):
return ItemListActionItem(theme: theme, title: "Clear Database", kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: {
guard let context = arguments.context else {
return
}
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: "All secret chats will be lost."),
ActionSheetButtonItem(title: "Clear Database", color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let databasePath = context.account.basePath + "/postbox/db"
let _ = try? FileManager.default.removeItem(atPath: databasePath)
preconditionFailure()
}),
])])
arguments.presentController(actionSheet, nil)
})
case let .resetDatabase(theme):
return ItemListActionItem(theme: theme, title: "Clear Database", kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: {
guard let context = arguments.context else {
return
}
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let actionSheet = ActionSheetController(presentationTheme: presentationData.theme)
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetTextItem(title: "All secret chats will be lost."),
ActionSheetButtonItem(title: "Clear Database", color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
let databasePath = context.account.basePath + "/postbox/db"
let _ = try? FileManager.default.removeItem(atPath: databasePath)
preconditionFailure()
}),
]), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
arguments.presentController(actionSheet, nil)
})
case let .resetHoles(theme):
return ItemListActionItem(theme: theme, title: "Reset Holes", kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: {
guard let context = arguments.context else {
return
}
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: nil))
arguments.presentController(controller, nil)
let _ = (context.account.postbox.transaction { transaction -> Void in
transaction.addHolesEverywhere(peerNamespaces: [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel], holeNamespace: Namespaces.Message.Cloud)
])])
arguments.presentController(actionSheet, nil)
})
case let .resetHoles(theme):
return ItemListActionItem(theme: theme, title: "Reset Holes", kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: {
guard let context = arguments.context else {
return
}
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: nil))
arguments.presentController(controller, nil)
let _ = (context.account.postbox.transaction { transaction -> Void in
transaction.addHolesEverywhere(peerNamespaces: [Namespaces.Peer.CloudUser, Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel], holeNamespace: Namespaces.Message.Cloud)
}
|> deliverOnMainQueue).start(completed: {
controller.dismiss()
})
})
case let .optimizeDatabase(theme):
return ItemListActionItem(theme: theme, title: "Optimize Database", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
guard let context = arguments.context else {
return
}
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: nil))
arguments.presentController(controller, nil)
let _ = (context.account.postbox.optimizeStorage()
})
case let .resetBiometricsData(theme):
return ItemListActionItem(theme: theme, title: "Reset Biometrics Data", kind: .destructive, alignment: .natural, sectionId: self.section, style: .blocks, action: {
let _ = updatePresentationPasscodeSettingsInteractively(accountManager: arguments.sharedContext.accountManager, { settings in
return settings.withUpdatedBiometricsDomainState(nil).withUpdatedShareBiometricsDomainState(nil)
}).start()
})
case let .optimizeDatabase(theme):
return ItemListActionItem(theme: theme, title: "Optimize Database", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
guard let context = arguments.context else {
return
}
let presentationData = arguments.sharedContext.currentPresentationData.with { $0 }
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .loading(cancelled: nil))
arguments.presentController(controller, nil)
let _ = (context.account.postbox.optimizeStorage()
|> deliverOnMainQueue).start(completed: {
controller.dismiss()
let controller = OverlayStatusController(theme: presentationData.theme, strings: presentationData.strings, type: .success)
arguments.presentController(controller, nil)
})
})
case let .photoPreview(theme, value):
return ItemListSwitchItem(theme: theme, title: "Photo Preview", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings
settings.chatListPhotos = value
return settings
})
}).start()
})
case let .knockoutWallpaper(theme, value):
return ItemListSwitchItem(theme: theme, title: "Knockout Wallpaper", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings
settings.knockoutWallpaper = value
return settings
})
}).start()
})
case let .versionInfo(theme):
let bundle = Bundle.main
let bundleId = bundle.bundleIdentifier ?? ""
let bundleVersion = bundle.infoDictionary?["CFBundleShortVersionString"] ?? ""
let bundleBuild = bundle.infoDictionary?[kCFBundleVersionKey as String] ?? ""
return ItemListTextItem(theme: theme, text: .plain("\(bundleId)\n\(bundleVersion) (\(bundleBuild))"), sectionId: self.section)
})
case let .photoPreview(theme, value):
return ItemListSwitchItem(theme: theme, title: "Photo Preview", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings
settings.chatListPhotos = value
return settings
})
}).start()
})
case let .knockoutWallpaper(theme, value):
return ItemListSwitchItem(theme: theme, title: "Knockout Wallpaper", value: value, sectionId: self.section, style: .blocks, updated: { value in
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings
settings.knockoutWallpaper = value
return settings
})
}).start()
})
case let .versionInfo(theme):
let bundle = Bundle.main
let bundleId = bundle.bundleIdentifier ?? ""
let bundleVersion = bundle.infoDictionary?["CFBundleShortVersionString"] ?? ""
let bundleBuild = bundle.infoDictionary?[kCFBundleVersionKey as String] ?? ""
return ItemListTextItem(theme: theme, text: .plain("\(bundleId)\n\(bundleVersion) (\(bundleBuild))"), sectionId: self.section)
}
}
}
@@ -524,7 +552,7 @@ public func debugController(sharedContext: SharedAccountContext, context: Accoun
var dismissImpl: (() -> Void)?
var getRootControllerImpl: (() -> UIViewController?)?
let arguments = DebugControllerArguments(sharedContext: sharedContext, context: context, presentController: { controller, arguments in
let arguments = DebugControllerArguments(sharedContext: sharedContext, context: context, mailComposeDelegate: DebugControllerMailComposeDelegate(), presentController: { controller, arguments in
presentControllerImpl?(controller, arguments)
}, pushController: { controller in
pushControllerImpl?(controller)
@@ -542,34 +570,34 @@ public func debugController(sharedContext: SharedAccountContext, context: Accoun
}
let signal = combineLatest(sharedContext.presentationData, sharedContext.accountManager.sharedData(keys: Set([SharedDataKeys.loggingSettings, ApplicationSpecificSharedDataKeys.mediaInputSettings, ApplicationSpecificSharedDataKeys.experimentalUISettings])))
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState<DebugControllerEntry>, DebugControllerEntry.ItemGenerationArguments)) in
let loggingSettings: LoggingSettings
if let value = sharedData.entries[SharedDataKeys.loggingSettings] as? LoggingSettings {
loggingSettings = value
} else {
loggingSettings = LoggingSettings.defaultSettings
}
let mediaInputSettings: MediaInputSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.mediaInputSettings] as? MediaInputSettings {
mediaInputSettings = value
} else {
mediaInputSettings = MediaInputSettings.defaultSettings
}
let experimentalSettings: ExperimentalUISettings = (sharedData.entries[ApplicationSpecificSharedDataKeys.experimentalUISettings] as? ExperimentalUISettings) ?? ExperimentalUISettings.defaultSettings
var leftNavigationButton: ItemListNavigationButton?
if modal {
leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})
}
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text("Debug"), leftNavigationButton: leftNavigationButton, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
let listState = ItemListNodeState(entries: debugControllerEntries(presentationData: presentationData, loggingSettings: loggingSettings, mediaInputSettings: mediaInputSettings, experimentalSettings: experimentalSettings, hasLegacyAppData: hasLegacyAppData), style: .blocks)
return (controllerState, (listState, arguments))
|> map { presentationData, sharedData -> (ItemListControllerState, (ItemListNodeState<DebugControllerEntry>, DebugControllerEntry.ItemGenerationArguments)) in
let loggingSettings: LoggingSettings
if let value = sharedData.entries[SharedDataKeys.loggingSettings] as? LoggingSettings {
loggingSettings = value
} else {
loggingSettings = LoggingSettings.defaultSettings
}
let mediaInputSettings: MediaInputSettings
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.mediaInputSettings] as? MediaInputSettings {
mediaInputSettings = value
} else {
mediaInputSettings = MediaInputSettings.defaultSettings
}
let experimentalSettings: ExperimentalUISettings = (sharedData.entries[ApplicationSpecificSharedDataKeys.experimentalUISettings] as? ExperimentalUISettings) ?? ExperimentalUISettings.defaultSettings
var leftNavigationButton: ItemListNavigationButton?
if modal {
leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
dismissImpl?()
})
}
let controllerState = ItemListControllerState(theme: presentationData.theme, title: .text("Debug"), leftNavigationButton: leftNavigationButton, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
let listState = ItemListNodeState(entries: debugControllerEntries(presentationData: presentationData, loggingSettings: loggingSettings, mediaInputSettings: mediaInputSettings, experimentalSettings: experimentalSettings, hasLegacyAppData: hasLegacyAppData), style: .blocks)
return (controllerState, (listState, arguments))
}

View File

@@ -99,6 +99,7 @@ final class AuthorizationSequencePhoneEntryController: ViewController {
guard let strongSelf = self else {
return
}
strongSelf.view.endEditing(true)
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 {