Merge commit '7621e2f8dec938cf48181c8b10afc9b01f444e68' into beta

This commit is contained in:
Ilya Laktyushin
2025-12-06 02:17:48 +04:00
commit 8344b97e03
28070 changed files with 7995182 additions and 0 deletions
@@ -0,0 +1,216 @@
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
}