mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 22:55:00 +00:00
Various improvements
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
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
|
||||
//TODO:localize
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text("Bots"), 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
|
||||
}
|
||||
Reference in New Issue
Block a user