mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
172 lines
5.5 KiB
Swift
172 lines
5.5 KiB
Swift
import UIKit
|
|
import Display
|
|
import SwiftSignalKit
|
|
import TelegramCore
|
|
import TelegramPresentationData
|
|
import ItemListUI
|
|
import ItemListPeerItem
|
|
import AccountContext
|
|
|
|
private final class BotListSettingsArguments {
|
|
let context: AccountContext
|
|
let openBot: (EnginePeer.Id) -> Void
|
|
|
|
init(
|
|
context: AccountContext,
|
|
openBot: @escaping (EnginePeer.Id) -> Void
|
|
) {
|
|
self.context = context
|
|
self.openBot = openBot
|
|
}
|
|
}
|
|
|
|
private enum BotListSettingsSection: Int32 {
|
|
case botItems
|
|
}
|
|
|
|
private enum BotListSettingsEntry: ItemListNodeEntry {
|
|
case botItem(peer: EnginePeer)
|
|
|
|
var section: ItemListSectionId {
|
|
switch self {
|
|
case .botItem:
|
|
return BotListSettingsSection.botItems.rawValue
|
|
}
|
|
}
|
|
|
|
var stableId: EnginePeer.Id {
|
|
switch self {
|
|
case let .botItem(peer):
|
|
return peer.id
|
|
}
|
|
}
|
|
|
|
static func ==(lhs: BotListSettingsEntry, rhs: BotListSettingsEntry) -> Bool {
|
|
switch lhs {
|
|
case let .botItem(peer):
|
|
if case .botItem(peer) = rhs {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
|
|
static func <(lhs: BotListSettingsEntry, rhs: BotListSettingsEntry) -> Bool {
|
|
switch lhs {
|
|
case let .botItem(lhsPeer):
|
|
switch rhs {
|
|
case let .botItem(rhsPeer):
|
|
if lhsPeer.compactDisplayTitle != rhsPeer.compactDisplayTitle {
|
|
return lhsPeer.compactDisplayTitle < rhsPeer.compactDisplayTitle
|
|
}
|
|
return lhsPeer.id < rhsPeer.id
|
|
}
|
|
}
|
|
}
|
|
|
|
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
|
let arguments = arguments as! BotListSettingsArguments
|
|
switch self {
|
|
case let .botItem(peer):
|
|
return ItemListPeerItem(
|
|
presentationData: presentationData,
|
|
dateTimeFormat: presentationData.dateTimeFormat,
|
|
nameDisplayOrder: presentationData.nameDisplayOrder,
|
|
context: arguments.context,
|
|
peer: peer,
|
|
presence: nil,
|
|
text: .none,
|
|
label: .disclosure(""),
|
|
editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false),
|
|
enabled: true,
|
|
selectable: true,
|
|
sectionId: self.section,
|
|
action: {
|
|
arguments.openBot(peer.id)
|
|
},
|
|
setPeerIdWithRevealedOptions: { _, _ in
|
|
},
|
|
removePeer: { _ in
|
|
},
|
|
style: .blocks
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
private struct BotListSettingsState: Equatable {
|
|
init() {
|
|
}
|
|
}
|
|
|
|
private func botListSettingsEntries(
|
|
presentationData: PresentationData,
|
|
peers: [EnginePeer]
|
|
) -> [BotListSettingsEntry] {
|
|
var entries: [BotListSettingsEntry] = []
|
|
|
|
for peer in peers {
|
|
entries.append(.botItem(peer: peer))
|
|
}
|
|
entries.sort(by: { $0 < $1 })
|
|
|
|
return entries
|
|
}
|
|
|
|
public func botListSettingsScreen(context: AccountContext) -> ViewController {
|
|
let initialState = BotListSettingsState()
|
|
|
|
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
|
let stateValue = Atomic(value: initialState)
|
|
let updateState: ((BotListSettingsState) -> BotListSettingsState) -> Void = { f in
|
|
statePromise.set(stateValue.modify { f($0) })
|
|
}
|
|
let _ = updateState
|
|
|
|
var pushControllerImpl: ((ViewController) -> Void)?
|
|
|
|
let actionsDisposable = DisposableSet()
|
|
|
|
let arguments = BotListSettingsArguments(
|
|
context: context,
|
|
openBot: { peerId in
|
|
pushControllerImpl?(botSettingsScreen(context: context, peerId: peerId))
|
|
}
|
|
)
|
|
|
|
let botPeerList: Signal<[EnginePeer], NoError> = context.engine.peers.botsWithBiometricState()
|
|
|> distinctUntilChanged
|
|
|> mapToSignal { peerIds -> Signal<[EnginePeer], NoError> in
|
|
return context.engine.data.subscribe(
|
|
EngineDataList(peerIds.map(TelegramEngine.EngineData.Item.Peer.Peer.init(id:)))
|
|
)
|
|
|> map { peers -> [EnginePeer] in
|
|
return peers.compactMap { $0 }
|
|
}
|
|
}
|
|
|
|
let signal = combineLatest(
|
|
context.sharedContext.presentationData,
|
|
statePromise.get(),
|
|
botPeerList
|
|
)
|
|
|> deliverOnMainQueue
|
|
|> map { presentationData, state, botPeerList -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
|
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.Settings_BotListSettings), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
|
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: botListSettingsEntries(presentationData: presentationData, peers: botPeerList), style: .blocks, animateChanges: true)
|
|
|
|
return (controllerState, (listState, arguments))
|
|
} |> afterDisposed {
|
|
actionsDisposable.dispose()
|
|
}
|
|
|
|
let controller = ItemListController(context: context, state: signal)
|
|
|
|
pushControllerImpl = { [weak controller] c in
|
|
(controller?.navigationController as? NavigationController)?.pushViewController(c, animated: true)
|
|
}
|
|
|
|
return controller
|
|
}
|