Swiftgram/submodules/SettingsUI/Sources/ArchiveSettingsController.swift
Ilya Laktyushin d6923ba451 Various fixes
2023-08-08 22:10:43 +02:00

217 lines
9.1 KiB
Swift

import Foundation
import UIKit
import Display
import SwiftSignalKit
import TelegramCore
import TelegramPresentationData
import TelegramUIPreferences
import ItemListUI
import PresentationDataUtils
import AccountContext
import UndoUI
private final class ArchiveSettingsControllerArguments {
let updateUnmuted: (Bool) -> Void
let updateFolders: (Bool) -> Void
let updateUnknown: (Bool?) -> Void
init(
updateUnmuted: @escaping (Bool) -> Void,
updateFolders: @escaping (Bool) -> Void,
updateUnknown: @escaping (Bool?) -> Void
) {
self.updateUnmuted = updateUnmuted
self.updateFolders = updateFolders
self.updateUnknown = updateUnknown
}
}
private enum ArchiveSettingsSection: Int32 {
case unmuted
case folders
case unknown
}
private enum ArchiveSettingsControllerEntry: ItemListNodeEntry {
case unmutedHeader
case unmutedValue(Bool)
case unmutedFooter
case foldersHeader
case foldersValue(Bool)
case foldersFooter
case unknownHeader
case unknownValue(isOn: Bool, isLocked: Bool)
case unknownFooter
var section: ItemListSectionId {
switch self {
case .unmutedHeader, .unmutedValue, .unmutedFooter:
return ArchiveSettingsSection.unmuted.rawValue
case .foldersHeader, .foldersValue, .foldersFooter:
return ArchiveSettingsSection.folders.rawValue
case .unknownHeader, .unknownValue, .unknownFooter:
return ArchiveSettingsSection.unknown.rawValue
}
}
var stableId: Int32 {
switch self {
case .unmutedHeader:
return 0
case .unmutedValue:
return 1
case .unmutedFooter:
return 2
case .foldersHeader:
return 3
case .foldersValue:
return 4
case .foldersFooter:
return 5
case .unknownHeader:
return 6
case .unknownValue:
return 7
case .unknownFooter:
return 8
}
}
static func <(lhs: ArchiveSettingsControllerEntry, rhs: ArchiveSettingsControllerEntry) -> Bool {
return lhs.stableId < rhs.stableId
}
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
let arguments = arguments as! ArchiveSettingsControllerArguments
switch self {
case .unmutedHeader:
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ArchiveSettings_UnmutedChatsHeader, sectionId: self.section)
case let .unmutedValue(value):
return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ArchiveSettings_KeepArchived, value: value, sectionId: self.section, style: .blocks, updated: { value in
arguments.updateUnmuted(value)
})
case .unmutedFooter:
return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.ArchiveSettings_UnmutedChatsFooter), sectionId: self.section)
case .foldersHeader:
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ArchiveSettings_FolderChatsHeader, sectionId: self.section)
case let .foldersValue(value):
return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ArchiveSettings_KeepArchived, value: value, sectionId: self.section, style: .blocks, updated: { value in
arguments.updateFolders(value)
})
case .foldersFooter:
return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.ArchiveSettings_FolderChatsFooter), sectionId: self.section)
case .unknownHeader:
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ArchiveSettings_UnknownChatsHeader, sectionId: self.section)
case let .unknownValue(isOn, isLocked):
return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ArchiveSettings_AutomaticallyArchive, value: isOn, enableInteractiveChanges: !isLocked, enabled: true, displayLocked: isLocked, sectionId: self.section, style: .blocks, updated: { value in
arguments.updateUnknown(value)
}, activatedWhileDisabled: {
arguments.updateUnknown(nil)
})
case .unknownFooter:
return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.ArchiveSettings_UnknownChatsFooter), sectionId: self.section)
}
}
}
private func archiveSettingsControllerEntries(
presentationData: PresentationData,
settings: GlobalPrivacySettings,
isPremium: Bool,
isPremiumEnabled: Bool
) -> [ArchiveSettingsControllerEntry] {
var entries: [ArchiveSettingsControllerEntry] = []
entries.append(.unmutedHeader)
entries.append(.unmutedValue(settings.keepArchivedUnmuted))
entries.append(.unmutedFooter)
if !settings.keepArchivedUnmuted {
entries.append(.foldersHeader)
entries.append(.foldersValue(settings.keepArchivedFolders))
entries.append(.foldersFooter)
}
if isPremium || isPremiumEnabled {
entries.append(.unknownHeader)
entries.append(.unknownValue(isOn: isPremium && settings.automaticallyArchiveAndMuteNonContacts, isLocked: !isPremium))
entries.append(.unknownFooter)
}
return entries
}
public func archiveSettingsController(context: AccountContext) -> ViewController {
let updateDisposable = MetaDisposable()
updateDisposable.set(context.engine.privacy.requestAccountPrivacySettings().start())
var presentUndoImpl: ((UndoOverlayContent) -> Void)?
var presentPremiumImpl: (() -> Void)?
let arguments = ArchiveSettingsControllerArguments(
updateUnmuted: { value in
let _ = context.engine.privacy.updateAccountKeepArchivedUnmuted(value: value).start()
},
updateFolders: { value in
let _ = context.engine.privacy.updateAccountKeepArchivedFolders(value: value).start()
},
updateUnknown: { value in
if let value {
let _ = context.engine.privacy.updateAccountAutoArchiveChats(value: value).start()
} else {
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
presentUndoImpl?(.premiumPaywall(title: nil, text: presentationData.strings.ArchiveSettings_TooltipPremiumRequired, customUndoText: nil, timeout: nil, linkAction: { _ in
presentPremiumImpl?()
}))
}
}
)
let signal = combineLatest(queue: .mainQueue(),
context.sharedContext.presentationData,
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.GlobalPrivacy()),
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App()),
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
)
|> deliverOnMainQueue
|> map { presentationData, settings, appConfiguration, accountPeer -> (ItemListControllerState, (ItemListNodeState, Any)) in
let isPremium = accountPeer?.isPremium ?? false
let isPremiumDisabled = PremiumConfiguration.with(appConfiguration: appConfiguration).isPremiumDisabled
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.ArchiveSettings_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: archiveSettingsControllerEntries(
presentationData: presentationData,
settings: settings,
isPremium: isPremium,
isPremiumEnabled: !isPremiumDisabled
), style: .blocks, animateChanges: true)
return (controllerState, (listState, arguments))
}
let controller = ItemListController(context: context, state: signal)
controller.navigationPresentation = .modal
presentUndoImpl = { [weak controller] content in
guard let controller else {
return
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
controller.present(UndoOverlayController(presentationData: presentationData, content: content, elevatedLayout: false, action: { _ in
return false
}), in: .current)
}
presentPremiumImpl = { [weak controller] in
guard let controller else {
return
}
let premiumController = context.sharedContext.makePremiumIntroController(context: context, source: .settings, forceDark: false, dismissed: nil)
controller.push(premiumController)
}
return controller
}