mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-17 03:40:18 +00:00
Group member search actions
This commit is contained in:
parent
2bea22c23b
commit
4881f49bf1
@ -473,7 +473,7 @@ public func channelAdminsController(account: Account, peerId: PeerId) -> ViewCon
|
|||||||
}
|
}
|
||||||
|
|
||||||
var pushControllerImpl: ((ViewController) -> Void)?
|
var pushControllerImpl: ((ViewController) -> Void)?
|
||||||
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
|
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
||||||
|
|
||||||
let actionsDisposable = DisposableSet()
|
let actionsDisposable = DisposableSet()
|
||||||
|
|
||||||
@ -669,6 +669,8 @@ public func channelAdminsController(account: Account, peerId: PeerId) -> ViewCon
|
|||||||
presentControllerImpl?(channelAdminController(account: account, peerId: peerId, adminId: participant.peerId, initialParticipant: participant, updated: { _ in
|
presentControllerImpl?(channelAdminController(account: account, peerId: peerId, adminId: participant.peerId, initialParticipant: participant, updated: { _ in
|
||||||
}), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
}), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
}
|
}
|
||||||
|
}, present: { c, a in
|
||||||
|
presentControllerImpl?(c, a)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -311,7 +311,7 @@ public func channelBlacklistController(account: Account, peerId: PeerId) -> View
|
|||||||
statePromise.set(stateValue.modify { f($0) })
|
statePromise.set(stateValue.modify { f($0) })
|
||||||
}
|
}
|
||||||
|
|
||||||
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
|
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
||||||
var pushControllerImpl: ((ViewController) -> Void)?
|
var pushControllerImpl: ((ViewController) -> Void)?
|
||||||
|
|
||||||
let actionsDisposable = DisposableSet()
|
let actionsDisposable = DisposableSet()
|
||||||
@ -477,6 +477,8 @@ public func channelBlacklistController(account: Account, peerId: PeerId) -> View
|
|||||||
arguments.openPeerInfo(rendered.peer)
|
arguments.openPeerInfo(rendered.peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, present: { c, a in
|
||||||
|
presentControllerImpl?(c, a)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -379,9 +379,29 @@ private final class ChannelMemberSingleCategoryListContext: ChannelMemberCategor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .recentSearch(query):
|
case let .recentSearch(query):
|
||||||
break
|
if let updated = updated, isParticipantMember(updated.participant), updated.peer.indexName.matchesByTokens(query) {
|
||||||
default:
|
var found = false
|
||||||
break
|
loop: for i in 0 ..< list.count {
|
||||||
|
if list[i].peer.id == updated.peer.id {
|
||||||
|
list[i] = updated
|
||||||
|
found = true
|
||||||
|
updatedList = true
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
list.insert(updated, at: 0)
|
||||||
|
updatedList = true
|
||||||
|
}
|
||||||
|
} else if let previous = previous, isParticipantMember(previous) {
|
||||||
|
loop: for i in 0 ..< list.count {
|
||||||
|
if list[i].peer.id == previous.peerId {
|
||||||
|
list.remove(at: i)
|
||||||
|
updatedList = true
|
||||||
|
break loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if updatedList {
|
if updatedList {
|
||||||
|
|||||||
@ -310,7 +310,7 @@ public func channelMembersController(account: Account, peerId: PeerId) -> ViewCo
|
|||||||
statePromise.set(stateValue.modify { f($0) })
|
statePromise.set(stateValue.modify { f($0) })
|
||||||
}
|
}
|
||||||
|
|
||||||
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
|
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
||||||
var pushControllerImpl: ((ViewController) -> Void)?
|
var pushControllerImpl: ((ViewController) -> Void)?
|
||||||
|
|
||||||
let actionsDisposable = DisposableSet()
|
let actionsDisposable = DisposableSet()
|
||||||
@ -444,6 +444,8 @@ public func channelMembersController(account: Account, peerId: PeerId) -> ViewCo
|
|||||||
pushControllerImpl?(infoController)
|
pushControllerImpl?(infoController)
|
||||||
// arguments.pushController(infoController)
|
// arguments.pushController(infoController)
|
||||||
}
|
}
|
||||||
|
}, present: { c, a in
|
||||||
|
presentControllerImpl?(c, a)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,7 +35,7 @@ private enum ChannelMembersSearchSection {
|
|||||||
|
|
||||||
private enum ChannelMembersSearchContent: Equatable {
|
private enum ChannelMembersSearchContent: Equatable {
|
||||||
case peer(Peer)
|
case peer(Peer)
|
||||||
case participant(participant: RenderedChannelParticipant, label: String?, revealActions: [ParticipantRevealAction], enabled: Bool)
|
case participant(participant: RenderedChannelParticipant, label: String?, revealActions: [ParticipantRevealAction], revealed: Bool, enabled: Bool)
|
||||||
|
|
||||||
static func ==(lhs: ChannelMembersSearchContent, rhs: ChannelMembersSearchContent) -> Bool {
|
static func ==(lhs: ChannelMembersSearchContent, rhs: ChannelMembersSearchContent) -> Bool {
|
||||||
switch lhs {
|
switch lhs {
|
||||||
@ -45,8 +45,8 @@ private enum ChannelMembersSearchContent: Equatable {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case let .participant(participant, label, revealActions, enabled):
|
case let .participant(participant, label, revealActions, revealed, enabled):
|
||||||
if case .participant(participant, label, revealActions, enabled) = rhs {
|
if case .participant(participant, label, revealActions, revealed, enabled) = rhs {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -58,12 +58,28 @@ private enum ChannelMembersSearchContent: Equatable {
|
|||||||
switch self {
|
switch self {
|
||||||
case let .peer(peer):
|
case let .peer(peer):
|
||||||
return peer.id
|
return peer.id
|
||||||
case let .participant(participant, _, _, _):
|
case let .participant(participant, _, _, _, _):
|
||||||
return participant.peer.id
|
return participant.peer.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final class ChannelMembersSearchContainerInteraction {
|
||||||
|
let peerSelected: (Peer, RenderedChannelParticipant?) -> Void
|
||||||
|
let setPeerIdWithRevealedOptions: (PeerId?, PeerId?) -> Void
|
||||||
|
let promotePeer: (RenderedChannelParticipant) -> Void
|
||||||
|
let restrictPeer: (RenderedChannelParticipant) -> Void
|
||||||
|
let removePeer: (PeerId) -> Void
|
||||||
|
|
||||||
|
init(peerSelected: @escaping (Peer, RenderedChannelParticipant?) -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, promotePeer: @escaping (RenderedChannelParticipant) -> Void, restrictPeer: @escaping (RenderedChannelParticipant) -> Void, removePeer: @escaping (PeerId) -> Void) {
|
||||||
|
self.peerSelected = peerSelected
|
||||||
|
self.setPeerIdWithRevealedOptions = setPeerIdWithRevealedOptions
|
||||||
|
self.promotePeer = promotePeer
|
||||||
|
self.restrictPeer = restrictPeer
|
||||||
|
self.removePeer = removePeer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final class ChannelMembersSearchEntry: Comparable, Identifiable {
|
private final class ChannelMembersSearchEntry: Comparable, Identifiable {
|
||||||
let index: Int
|
let index: Int
|
||||||
let content: ChannelMembersSearchContent
|
let content: ChannelMembersSearchContent
|
||||||
@ -87,31 +103,40 @@ private final class ChannelMembersSearchEntry: Comparable, Identifiable {
|
|||||||
return lhs.index < rhs.index
|
return lhs.index < rhs.index
|
||||||
}
|
}
|
||||||
|
|
||||||
func item(account: Account, theme: PresentationTheme, strings: PresentationStrings, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, peerSelected: @escaping (Peer, RenderedChannelParticipant?) -> Void) -> ListViewItem {
|
func item(account: Account, theme: PresentationTheme, strings: PresentationStrings, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, interaction: ChannelMembersSearchContainerInteraction) -> ListViewItem {
|
||||||
switch self.content {
|
switch self.content {
|
||||||
case let .peer(peer):
|
case let .peer(peer):
|
||||||
return ContactsPeerItem(theme: theme, strings: strings, sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, account: account, peerMode: .peer, peer: .peer(peer: peer, chatPeer: peer), status: .none, enabled: true, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: self.section.chatListHeaderType.flatMap({ ChatListSearchItemHeader(type: $0, theme: theme, strings: strings, actionTitle: nil, action: nil) }), action: { _ in
|
return ContactsPeerItem(theme: theme, strings: strings, sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, account: account, peerMode: .peer, peer: .peer(peer: peer, chatPeer: peer), status: .none, enabled: true, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: self.section.chatListHeaderType.flatMap({ ChatListSearchItemHeader(type: $0, theme: theme, strings: strings, actionTitle: nil, action: nil) }), action: { _ in
|
||||||
peerSelected(peer, nil)
|
interaction.peerSelected(peer, nil)
|
||||||
})
|
})
|
||||||
case let .participant(participant, label, revealActions, enabled):
|
case let .participant(participant, label, revealActions, revealed, enabled):
|
||||||
|
let status: ContactsPeerItemStatus
|
||||||
|
if let label = label {
|
||||||
|
status = .custom(label)
|
||||||
|
} else {
|
||||||
|
status = .none
|
||||||
|
}
|
||||||
|
|
||||||
var options: [ItemListPeerItemRevealOption] = []
|
var options: [ItemListPeerItemRevealOption] = []
|
||||||
for action in revealActions {
|
for action in revealActions {
|
||||||
options.append(ItemListPeerItemRevealOption(type: action.type, title: action.title, action: {
|
options.append(ItemListPeerItemRevealOption(type: action.type, title: action.title, action: {
|
||||||
switch action.action {
|
switch action.action {
|
||||||
case .promote:
|
case .promote:
|
||||||
//arguments.promotePeer(participant)
|
interaction.promotePeer(participant)
|
||||||
break
|
break
|
||||||
case .restrict:
|
case .restrict:
|
||||||
//arguments.restrictPeer(participant)
|
interaction.restrictPeer(participant)
|
||||||
break
|
break
|
||||||
case .remove:
|
case .remove:
|
||||||
//arguments.removePeer(peer.id)
|
interaction.removePeer(participant.peer.id)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
return ContactsPeerItem(theme: theme, strings: strings, sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, account: account, peerMode: .peer, peer: .peer(peer: participant.peer, chatPeer: participant.peer), status: .none, enabled: enabled, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: false), index: nil, header: self.section.chatListHeaderType.flatMap({ ChatListSearchItemHeader(type: $0, theme: theme, strings: strings, actionTitle: nil, action: nil) }), action: { _ in
|
return ContactsPeerItem(theme: theme, strings: strings, sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, account: account, peerMode: .peer, peer: .peer(peer: participant.peer, chatPeer: participant.peer), status: status, enabled: enabled, selection: .none, editing: ContactsPeerItemEditing(editable: false, editing: false, revealed: revealed), options: options, index: nil, header: self.section.chatListHeaderType.flatMap({ ChatListSearchItemHeader(type: $0, theme: theme, strings: strings, actionTitle: nil, action: nil) }), action: { _ in
|
||||||
peerSelected(participant.peer, participant)
|
interaction.peerSelected(participant.peer, participant)
|
||||||
|
}, setPeerIdWithRevealedOptions: { peerId, fromPeerId in
|
||||||
|
interaction.setPeerIdWithRevealedOptions(peerId, fromPeerId)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,16 +148,21 @@ struct ChannelMembersSearchContainerTransition {
|
|||||||
let isSearching: Bool
|
let isSearching: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
private func channelMembersSearchContainerPreparedRecentTransition(from fromEntries: [ChannelMembersSearchEntry], to toEntries: [ChannelMembersSearchEntry], isSearching: Bool, account: Account, theme: PresentationTheme, strings: PresentationStrings, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, peerSelected: @escaping (Peer, RenderedChannelParticipant?) -> Void) -> ChannelMembersSearchContainerTransition {
|
private func channelMembersSearchContainerPreparedRecentTransition(from fromEntries: [ChannelMembersSearchEntry], to toEntries: [ChannelMembersSearchEntry], isSearching: Bool, account: Account, theme: PresentationTheme, strings: PresentationStrings, nameSortOrder: PresentationPersonNameOrder, nameDisplayOrder: PresentationPersonNameOrder, interaction: ChannelMembersSearchContainerInteraction) -> ChannelMembersSearchContainerTransition {
|
||||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||||
|
|
||||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
||||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: theme, strings: strings, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, peerSelected: peerSelected), directionHint: nil) }
|
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: theme, strings: strings, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, interaction: interaction), directionHint: nil) }
|
||||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: theme, strings: strings, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, peerSelected: peerSelected), directionHint: nil) }
|
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, theme: theme, strings: strings, nameSortOrder: nameSortOrder, nameDisplayOrder: nameDisplayOrder, interaction: interaction), directionHint: nil) }
|
||||||
|
|
||||||
return ChannelMembersSearchContainerTransition(deletions: deletions, insertions: insertions, updates: updates, isSearching: isSearching)
|
return ChannelMembersSearchContainerTransition(deletions: deletions, insertions: insertions, updates: updates, isSearching: isSearching)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private struct ChannelMembersSearchContainerState: Equatable {
|
||||||
|
var revealedPeerId: PeerId?
|
||||||
|
var removingParticipantIds = Set<PeerId>()
|
||||||
|
}
|
||||||
|
|
||||||
final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNode {
|
final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNode {
|
||||||
private let account: Account
|
private let account: Account
|
||||||
private let openPeer: (Peer, RenderedChannelParticipant?) -> Void
|
private let openPeer: (Peer, RenderedChannelParticipant?) -> Void
|
||||||
@ -150,9 +180,11 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
private var presentationDataDisposable: Disposable?
|
private var presentationDataDisposable: Disposable?
|
||||||
|
|
||||||
|
private let removeMemberDisposable = MetaDisposable()
|
||||||
|
|
||||||
private let themeAndStringsPromise: Promise<(PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder)>
|
private let themeAndStringsPromise: Promise<(PresentationTheme, PresentationStrings, PresentationPersonNameOrder, PresentationPersonNameOrder)>
|
||||||
|
|
||||||
init(account: Account, peerId: PeerId, mode: ChannelMembersSearchMode, filters: [ChannelMembersSearchFilter], openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, updateActivity: @escaping(Bool)->Void) {
|
init(account: Account, peerId: PeerId, mode: ChannelMembersSearchMode, filters: [ChannelMembersSearchFilter], openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, updateActivity: @escaping (Bool) -> Void, present: @escaping (ViewController, Any?) -> Void) {
|
||||||
self.account = account
|
self.account = account
|
||||||
self.openPeer = openPeer
|
self.openPeer = openPeer
|
||||||
self.mode = mode
|
self.mode = mode
|
||||||
@ -173,9 +205,80 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
self.addSubnode(self.dimNode)
|
self.addSubnode(self.dimNode)
|
||||||
self.addSubnode(self.listNode)
|
self.addSubnode(self.listNode)
|
||||||
|
|
||||||
|
let statePromise = ValuePromise(ChannelMembersSearchContainerState(), ignoreRepeated: true)
|
||||||
|
let stateValue = Atomic(value: ChannelMembersSearchContainerState())
|
||||||
|
let updateState: ((ChannelMembersSearchContainerState) -> ChannelMembersSearchContainerState) -> Void = { f in
|
||||||
|
statePromise.set(stateValue.modify { f($0) })
|
||||||
|
}
|
||||||
|
|
||||||
|
let removeMemberDisposable = self.removeMemberDisposable
|
||||||
|
let interaction = ChannelMembersSearchContainerInteraction(peerSelected: { peer, participant in
|
||||||
|
openPeer(peer, participant)
|
||||||
|
}, setPeerIdWithRevealedOptions: { peerId, fromPeerId in
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
if (peerId == nil && fromPeerId == state.revealedPeerId) || (peerId != nil && fromPeerId == nil) {
|
||||||
|
state.revealedPeerId = peerId
|
||||||
|
}
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}, promotePeer: { participant in
|
||||||
|
present(channelAdminController(account: account, peerId: peerId, adminId: participant.peer.id, initialParticipant: participant.participant, updated: { _ in
|
||||||
|
}), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
|
}, restrictPeer: { participant in
|
||||||
|
present(channelBannedMemberController(account: account, peerId: peerId, memberId: participant.peer.id, initialParticipant: participant.participant, updated: { _ in
|
||||||
|
}), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
|
}, removePeer: { memberId in
|
||||||
|
let signal = account.postbox.loadedPeerWithId(memberId)
|
||||||
|
|> deliverOnMainQueue
|
||||||
|
|> mapToSignal { peer -> Signal<Bool, NoError> in
|
||||||
|
let result = ValuePromise<Bool>()
|
||||||
|
result.set(true)
|
||||||
|
return result.get()
|
||||||
|
}
|
||||||
|
|> mapToSignal { value -> Signal<Void, NoError> in
|
||||||
|
if value {
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.removingParticipantIds.insert(memberId)
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
if peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
|
return account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(account: account, peerId: peerId, memberId: memberId, bannedRights: TelegramChannelBannedRights(flags: [.banReadMessages], untilDate: Int32.max))
|
||||||
|
|> afterDisposed {
|
||||||
|
Queue.mainQueue().async {
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.removingParticipantIds.remove(memberId)
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return removePeerMember(account: account, peerId: peerId, memberId: memberId)
|
||||||
|
|> deliverOnMainQueue
|
||||||
|
|> afterDisposed {
|
||||||
|
updateState { state in
|
||||||
|
var state = state
|
||||||
|
state.removingParticipantIds.remove(memberId)
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
removeMemberDisposable.set(signal.start())
|
||||||
|
})
|
||||||
|
|
||||||
let themeAndStringsPromise = self.themeAndStringsPromise
|
let themeAndStringsPromise = self.themeAndStringsPromise
|
||||||
let foundItems = searchQuery.get()
|
let foundItems = combineLatest(searchQuery.get(), account.postbox.multiplePeersView([peerId]) |> take(1))
|
||||||
|> mapToSignal { query -> Signal<[ChannelMembersSearchEntry]?, NoError> in
|
|> mapToSignal { query, peerView -> Signal<[ChannelMembersSearchEntry]?, NoError> in
|
||||||
|
guard let channel = peerView.peers[peerId] as? TelegramChannel else {
|
||||||
|
return .single(nil)
|
||||||
|
}
|
||||||
updateActivity(true)
|
updateActivity(true)
|
||||||
if let query = query, !query.isEmpty {
|
if let query = query, !query.isEmpty {
|
||||||
let foundGroupMembers: Signal<[RenderedChannelParticipant], NoError>
|
let foundGroupMembers: Signal<[RenderedChannelParticipant], NoError>
|
||||||
@ -187,7 +290,6 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
let (disposable, _) = account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.recent(postbox: account.postbox, network: account.network, accountPeerId: account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
let (disposable, _) = account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.recent(postbox: account.postbox, network: account.network, accountPeerId: account.peerId, peerId: peerId, searchQuery: query, updated: { state in
|
||||||
if case .ready = state.loadingState {
|
if case .ready = state.loadingState {
|
||||||
subscriber.putNext(state.list)
|
subscriber.putNext(state.list)
|
||||||
subscriber.putCompletion()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return disposable
|
return disposable
|
||||||
@ -218,7 +320,8 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
return disposable
|
return disposable
|
||||||
} |> runOn(Queue.mainQueue())
|
}
|
||||||
|
|> runOn(Queue.mainQueue())
|
||||||
foundMembers = .single([])
|
foundMembers = .single([])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,8 +337,8 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
foundRemotePeers = .single(([], []))
|
foundRemotePeers = .single(([], []))
|
||||||
}
|
}
|
||||||
|
|
||||||
return combineLatest(foundGroupMembers, foundMembers, foundContacts, foundRemotePeers, themeAndStringsPromise.get())
|
return combineLatest(foundGroupMembers, foundMembers, foundContacts, foundRemotePeers, themeAndStringsPromise.get(), statePromise.get())
|
||||||
|> map { foundGroupMembers, foundMembers, foundContacts, foundRemotePeers, themeAndStrings -> [ChannelMembersSearchEntry]? in
|
|> map { foundGroupMembers, foundMembers, foundContacts, foundRemotePeers, themeAndStrings, state -> [ChannelMembersSearchEntry]? in
|
||||||
var entries: [ChannelMembersSearchEntry] = []
|
var entries: [ChannelMembersSearchEntry] = []
|
||||||
|
|
||||||
var existingPeerIds = Set<PeerId>()
|
var existingPeerIds = Set<PeerId>()
|
||||||
@ -267,6 +370,39 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
section = .none
|
section = .none
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var canPromote: Bool
|
||||||
|
var canRestrict: Bool
|
||||||
|
switch participant.participant {
|
||||||
|
case .creator:
|
||||||
|
canPromote = false
|
||||||
|
canRestrict = false
|
||||||
|
case let .member(_, _, adminRights, bannedRights):
|
||||||
|
if channel.hasAdminRights([.canAddAdmins]) {
|
||||||
|
canPromote = true
|
||||||
|
} else {
|
||||||
|
canPromote = false
|
||||||
|
}
|
||||||
|
if channel.hasAdminRights([.canBanUsers]) {
|
||||||
|
canRestrict = true
|
||||||
|
} else {
|
||||||
|
canRestrict = false
|
||||||
|
}
|
||||||
|
if canPromote {
|
||||||
|
if let bannedRights = bannedRights {
|
||||||
|
if bannedRights.restrictedBy != account.peerId && !channel.flags.contains(.isCreator) {
|
||||||
|
canPromote = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if canRestrict {
|
||||||
|
if let adminRights = adminRights {
|
||||||
|
if adminRights.promotedBy != account.peerId && !channel.flags.contains(.isCreator) {
|
||||||
|
canRestrict = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var label: String?
|
var label: String?
|
||||||
var enabled = true
|
var enabled = true
|
||||||
if case .banAndPromoteActions = mode {
|
if case .banAndPromoteActions = mode {
|
||||||
@ -274,7 +410,32 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
label = themeAndStrings.1.Channel_Management_LabelCreator
|
label = themeAndStrings.1.Channel_Management_LabelCreator
|
||||||
enabled = false
|
enabled = false
|
||||||
}
|
}
|
||||||
|
} else if case .searchMembers = mode {
|
||||||
|
switch participant.participant {
|
||||||
|
case .creator:
|
||||||
|
label = themeAndStrings.1.Channel_Management_LabelCreator
|
||||||
|
case let .member(member):
|
||||||
|
if member.adminInfo != nil {
|
||||||
|
label = themeAndStrings.1.Channel_Management_LabelEditor
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.removingParticipantIds.contains(participant.peer.id) {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
var peerActions: [ParticipantRevealAction] = []
|
||||||
|
if case .searchMembers = mode {
|
||||||
|
if canPromote {
|
||||||
|
peerActions.append(ParticipantRevealAction(type: .neutral, title: themeAndStrings.1.GroupInfo_ActionPromote, action: .promote))
|
||||||
|
}
|
||||||
|
if canRestrict {
|
||||||
|
peerActions.append(ParticipantRevealAction(type: .warning, title: themeAndStrings.1.GroupInfo_ActionRestrict, action: .restrict))
|
||||||
|
peerActions.append(ParticipantRevealAction(type: .destructive, title: themeAndStrings.1.Common_Delete, action: .remove))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch mode {
|
switch mode {
|
||||||
case .searchAdmins:
|
case .searchAdmins:
|
||||||
switch participant.participant {
|
switch participant.participant {
|
||||||
@ -299,7 +460,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
entries.append(ChannelMembersSearchEntry(index: index, content: .participant(participant: participant, label: label, revealActions: [], enabled: enabled), section: section))
|
entries.append(ChannelMembersSearchEntry(index: index, content: .participant(participant: participant, label: label, revealActions: peerActions, revealed: state.revealedPeerId == participant.peer.id, enabled: enabled), section: section))
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,7 +486,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
entries.append(ChannelMembersSearchEntry(index: index, content: .participant(participant: participant, label: label, revealActions: [], enabled: enabled), section: section))
|
entries.append(ChannelMembersSearchEntry(index: index, content: .participant(participant: participant, label: label, revealActions: [], revealed: false, enabled: enabled), section: section))
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -371,7 +532,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
let previousEntries = previousSearchItems.swap(entries)
|
let previousEntries = previousSearchItems.swap(entries)
|
||||||
updateActivity(false)
|
updateActivity(false)
|
||||||
let firstTime = previousEntries == nil
|
let firstTime = previousEntries == nil
|
||||||
let transition = channelMembersSearchContainerPreparedRecentTransition(from: previousEntries ?? [], to: entries ?? [], isSearching: entries != nil, account: account, theme: themeAndStrings.0, strings: themeAndStrings.1, nameSortOrder: themeAndStrings.2, nameDisplayOrder: themeAndStrings.3, peerSelected: openPeer)
|
let transition = channelMembersSearchContainerPreparedRecentTransition(from: previousEntries ?? [], to: entries ?? [], isSearching: entries != nil, account: account, theme: themeAndStrings.0, strings: themeAndStrings.1, nameSortOrder: themeAndStrings.2, nameDisplayOrder: themeAndStrings.3, interaction: interaction)
|
||||||
strongSelf.enqueueTransition(transition, firstTime: firstTime)
|
strongSelf.enqueueTransition(transition, firstTime: firstTime)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -398,6 +559,7 @@ final class ChannelMembersSearchContainerNode: SearchDisplayControllerContentNod
|
|||||||
deinit {
|
deinit {
|
||||||
self.searchDisposable.dispose()
|
self.searchDisposable.dispose()
|
||||||
self.presentationDataDisposable?.dispose()
|
self.presentationDataDisposable?.dispose()
|
||||||
|
self.removeMemberDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func didLoad() {
|
override func didLoad() {
|
||||||
|
|||||||
@ -70,6 +70,9 @@ final class ChannelMembersSearchController: ViewController {
|
|||||||
self?.dismiss()
|
self?.dismiss()
|
||||||
self?.openPeer(peer, participant)
|
self?.openPeer(peer, participant)
|
||||||
}
|
}
|
||||||
|
self.controllerNode.present = { [weak self] c, a in
|
||||||
|
self?.present(c, in: .window(.root), with: a)
|
||||||
|
}
|
||||||
|
|
||||||
self.displayNodeDidLoad()
|
self.displayNodeDidLoad()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -121,6 +121,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
|
|||||||
var requestActivateSearch: (() -> Void)?
|
var requestActivateSearch: (() -> Void)?
|
||||||
var requestDeactivateSearch: (() -> Void)?
|
var requestDeactivateSearch: (() -> Void)?
|
||||||
var requestOpenPeerFromSearch: ((Peer, RenderedChannelParticipant?) -> Void)?
|
var requestOpenPeerFromSearch: ((Peer, RenderedChannelParticipant?) -> Void)?
|
||||||
|
var present: ((ViewController, Any?) -> Void)?
|
||||||
|
|
||||||
var themeAndStrings: (PresentationTheme, PresentationStrings)
|
var themeAndStrings: (PresentationTheme, PresentationStrings)
|
||||||
|
|
||||||
@ -292,6 +293,8 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
|
|||||||
self?.requestOpenPeerFromSearch?(peer, participant)
|
self?.requestOpenPeerFromSearch?(peer, participant)
|
||||||
}, updateActivity: { value in
|
}, updateActivity: { value in
|
||||||
|
|
||||||
|
}, present: { [weak self] c, a in
|
||||||
|
self?.present?(c, a)
|
||||||
}), cancel: { [weak self] in
|
}), cancel: { [weak self] in
|
||||||
if let requestDeactivateSearch = self?.requestDeactivateSearch {
|
if let requestDeactivateSearch = self?.requestDeactivateSearch {
|
||||||
requestDeactivateSearch()
|
requestDeactivateSearch()
|
||||||
|
|||||||
@ -115,6 +115,7 @@ class ContactsPeerItem: ListViewItem {
|
|||||||
let enabled: Bool
|
let enabled: Bool
|
||||||
let selection: ContactsPeerItemSelection
|
let selection: ContactsPeerItemSelection
|
||||||
let editing: ContactsPeerItemEditing
|
let editing: ContactsPeerItemEditing
|
||||||
|
let options: [ItemListPeerItemRevealOption]
|
||||||
let action: (ContactsPeerItemPeer) -> Void
|
let action: (ContactsPeerItemPeer) -> Void
|
||||||
let setPeerIdWithRevealedOptions: ((PeerId?, PeerId?) -> Void)?
|
let setPeerIdWithRevealedOptions: ((PeerId?, PeerId?) -> Void)?
|
||||||
let deletePeer: ((PeerId) -> Void)?
|
let deletePeer: ((PeerId) -> Void)?
|
||||||
@ -125,7 +126,7 @@ class ContactsPeerItem: ListViewItem {
|
|||||||
|
|
||||||
let header: ListViewItemHeader?
|
let header: ListViewItemHeader?
|
||||||
|
|
||||||
init(theme: PresentationTheme, strings: PresentationStrings, sortOrder: PresentationPersonNameOrder, displayOrder: PresentationPersonNameOrder, account: Account, peerMode: ContactsPeerItemPeerMode, peer: ContactsPeerItemPeer, status: ContactsPeerItemStatus, badge: ContactsPeerItemBadge? = nil, enabled: Bool, selection: ContactsPeerItemSelection, editing: ContactsPeerItemEditing, index: PeerNameIndex?, header: ListViewItemHeader?, action: @escaping (ContactsPeerItemPeer) -> Void, setPeerIdWithRevealedOptions: ((PeerId?, PeerId?) -> Void)? = nil, deletePeer: ((PeerId) -> Void)? = nil) {
|
init(theme: PresentationTheme, strings: PresentationStrings, sortOrder: PresentationPersonNameOrder, displayOrder: PresentationPersonNameOrder, account: Account, peerMode: ContactsPeerItemPeerMode, peer: ContactsPeerItemPeer, status: ContactsPeerItemStatus, badge: ContactsPeerItemBadge? = nil, enabled: Bool, selection: ContactsPeerItemSelection, editing: ContactsPeerItemEditing, options: [ItemListPeerItemRevealOption] = [], index: PeerNameIndex?, header: ListViewItemHeader?, action: @escaping (ContactsPeerItemPeer) -> Void, setPeerIdWithRevealedOptions: ((PeerId?, PeerId?) -> Void)? = nil, deletePeer: ((PeerId) -> Void)? = nil) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
self.sortOrder = sortOrder
|
self.sortOrder = sortOrder
|
||||||
@ -138,6 +139,7 @@ class ContactsPeerItem: ListViewItem {
|
|||||||
self.enabled = enabled
|
self.enabled = enabled
|
||||||
self.selection = selection
|
self.selection = selection
|
||||||
self.editing = editing
|
self.editing = editing
|
||||||
|
self.options = options
|
||||||
self.action = action
|
self.action = action
|
||||||
self.setPeerIdWithRevealedOptions = setPeerIdWithRevealedOptions
|
self.setPeerIdWithRevealedOptions = setPeerIdWithRevealedOptions
|
||||||
self.deletePeer = deletePeer
|
self.deletePeer = deletePeer
|
||||||
@ -562,6 +564,32 @@ class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
|||||||
titleFrame = CGRect(origin: CGPoint(x: leftInset, y: 13.0), size: titleLayout.size)
|
titleFrame = CGRect(origin: CGPoint(x: leftInset, y: 13.0), size: titleLayout.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let peerRevealOptions: [ItemListRevealOption]
|
||||||
|
if item.enabled {
|
||||||
|
var mappedOptions: [ItemListRevealOption] = []
|
||||||
|
var index: Int32 = 0
|
||||||
|
for option in item.options {
|
||||||
|
let color: UIColor
|
||||||
|
let textColor: UIColor
|
||||||
|
switch option.type {
|
||||||
|
case .neutral:
|
||||||
|
color = item.theme.list.itemDisclosureActions.constructive.fillColor
|
||||||
|
textColor = item.theme.list.itemDisclosureActions.constructive.foregroundColor
|
||||||
|
case .warning:
|
||||||
|
color = item.theme.list.itemDisclosureActions.warning.fillColor
|
||||||
|
textColor = item.theme.list.itemDisclosureActions.warning.foregroundColor
|
||||||
|
case .destructive:
|
||||||
|
color = item.theme.list.itemDisclosureActions.destructive.fillColor
|
||||||
|
textColor = item.theme.list.itemDisclosureActions.destructive.foregroundColor
|
||||||
|
}
|
||||||
|
mappedOptions.append(ItemListRevealOption(key: index, title: option.title, icon: .none, color: color, textColor: textColor))
|
||||||
|
index += 1
|
||||||
|
}
|
||||||
|
peerRevealOptions = mappedOptions
|
||||||
|
} else {
|
||||||
|
peerRevealOptions = []
|
||||||
|
}
|
||||||
|
|
||||||
return (nodeLayout, { [weak self] in
|
return (nodeLayout, { [weak self] in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
return (.complete(), { [weak strongSelf] animated, synchronousLoads in
|
return (.complete(), { [weak strongSelf] animated, synchronousLoads in
|
||||||
@ -710,12 +738,12 @@ class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
|||||||
|
|
||||||
strongSelf.updateLayout(size: nodeLayout.contentSize, leftInset: params.leftInset, rightInset: params.rightInset)
|
strongSelf.updateLayout(size: nodeLayout.contentSize, leftInset: params.leftInset, rightInset: params.rightInset)
|
||||||
|
|
||||||
|
|
||||||
if item.editing.editable {
|
if item.editing.editable {
|
||||||
strongSelf.setRevealOptions((left: [], right: [ItemListRevealOption(key: 0, title: item.strings.Common_Delete, icon: .none, color: item.theme.list.itemDisclosureActions.destructive.fillColor, textColor: item.theme.list.itemDisclosureActions.destructive.foregroundColor)]))
|
strongSelf.setRevealOptions((left: [], right: [ItemListRevealOption(key: 0, title: item.strings.Common_Delete, icon: .none, color: item.theme.list.itemDisclosureActions.destructive.fillColor, textColor: item.theme.list.itemDisclosureActions.destructive.foregroundColor)]))
|
||||||
strongSelf.setRevealOptionsOpened(item.editing.revealed, animated: animated)
|
strongSelf.setRevealOptionsOpened(item.editing.revealed, animated: animated)
|
||||||
} else {
|
} else {
|
||||||
strongSelf.setRevealOptions((left: [], right: []))
|
strongSelf.setRevealOptions((left: [], right: peerRevealOptions))
|
||||||
|
strongSelf.setRevealOptionsOpened(item.editing.revealed, animated: animated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -800,6 +828,7 @@ class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
|||||||
|
|
||||||
override func revealOptionSelected(_ option: ItemListRevealOption, animated: Bool) {
|
override func revealOptionSelected(_ option: ItemListRevealOption, animated: Bool) {
|
||||||
if let item = self.item {
|
if let item = self.item {
|
||||||
|
if item.editing.editable {
|
||||||
switch item.peer {
|
switch item.peer {
|
||||||
case let .peer(peer, chatPeer):
|
case let .peer(peer, chatPeer):
|
||||||
if let peer = chatPeer ?? peer {
|
if let peer = chatPeer ?? peer {
|
||||||
@ -808,6 +837,9 @@ class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
|||||||
case .deviceContact:
|
case .deviceContact:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
item.options[Int(option.key)].action()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.setRevealOptionsOpened(false, animated: true)
|
self.setRevealOptionsOpened(false, animated: true)
|
||||||
|
|||||||
@ -1780,6 +1780,8 @@ public func groupInfoController(account: Account, peerId: PeerId) -> ViewControl
|
|||||||
if let infoController = peerInfoController(account: account, peer: peer) {
|
if let infoController = peerInfoController(account: account, peer: peer) {
|
||||||
arguments.pushController(infoController)
|
arguments.pushController(infoController)
|
||||||
}
|
}
|
||||||
|
}, present: { c, a in
|
||||||
|
presentControllerImpl?(c, a)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,15 +10,19 @@ final class ChannelMembersSearchItem: ItemListControllerSearch {
|
|||||||
let peerId: PeerId
|
let peerId: PeerId
|
||||||
let cancel: () -> Void
|
let cancel: () -> Void
|
||||||
let openPeer: (Peer, RenderedChannelParticipant?) -> Void
|
let openPeer: (Peer, RenderedChannelParticipant?) -> Void
|
||||||
|
let present: (ViewController, Any?) -> Void
|
||||||
let searchMode: ChannelMembersSearchMode
|
let searchMode: ChannelMembersSearchMode
|
||||||
|
|
||||||
private var updateActivity: ((Bool) -> Void)?
|
private var updateActivity: ((Bool) -> Void)?
|
||||||
private var activity: ValuePromise<Bool> = ValuePromise(ignoreRepeated: false)
|
private var activity: ValuePromise<Bool> = ValuePromise(ignoreRepeated: false)
|
||||||
private let activityDisposable = MetaDisposable()
|
private let activityDisposable = MetaDisposable()
|
||||||
init(account: Account, peerId: PeerId, searchMode: ChannelMembersSearchMode = .searchMembers, cancel: @escaping () -> Void, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void) {
|
|
||||||
|
init(account: Account, peerId: PeerId, searchMode: ChannelMembersSearchMode = .searchMembers, cancel: @escaping () -> Void, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, present: @escaping (ViewController, Any?) -> Void) {
|
||||||
self.account = account
|
self.account = account
|
||||||
self.peerId = peerId
|
self.peerId = peerId
|
||||||
self.cancel = cancel
|
self.cancel = cancel
|
||||||
self.openPeer = openPeer
|
self.openPeer = openPeer
|
||||||
|
self.present = present
|
||||||
self.searchMode = searchMode
|
self.searchMode = searchMode
|
||||||
activityDisposable.set((activity.get() |> mapToSignal { value -> Signal<Bool, NoError> in
|
activityDisposable.set((activity.get() |> mapToSignal { value -> Signal<Bool, NoError> in
|
||||||
if value {
|
if value {
|
||||||
@ -32,7 +36,7 @@ final class ChannelMembersSearchItem: ItemListControllerSearch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
activityDisposable.dispose()
|
self.activityDisposable.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEqual(to: ItemListControllerSearch) -> Bool {
|
func isEqual(to: ItemListControllerSearch) -> Bool {
|
||||||
@ -63,6 +67,8 @@ final class ChannelMembersSearchItem: ItemListControllerSearch {
|
|||||||
func node(current: ItemListControllerSearchNode?) -> ItemListControllerSearchNode {
|
func node(current: ItemListControllerSearchNode?) -> ItemListControllerSearchNode {
|
||||||
return ChannelMembersSearchItemNode(account: self.account, peerId: self.peerId, searchMode: self.searchMode, openPeer: self.openPeer, cancel: self.cancel, updateActivity: { [weak self] value in
|
return ChannelMembersSearchItemNode(account: self.account, peerId: self.peerId, searchMode: self.searchMode, openPeer: self.openPeer, cancel: self.cancel, updateActivity: { [weak self] value in
|
||||||
self?.activity.set(value)
|
self?.activity.set(value)
|
||||||
|
}, present: { [weak self] c, a in
|
||||||
|
self?.present(c, a)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,10 +76,10 @@ final class ChannelMembersSearchItem: ItemListControllerSearch {
|
|||||||
private final class ChannelMembersSearchItemNode: ItemListControllerSearchNode {
|
private final class ChannelMembersSearchItemNode: ItemListControllerSearchNode {
|
||||||
private let containerNode: ChannelMembersSearchContainerNode
|
private let containerNode: ChannelMembersSearchContainerNode
|
||||||
|
|
||||||
init(account: Account, peerId: PeerId, searchMode: ChannelMembersSearchMode, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, cancel: @escaping () -> Void, updateActivity: @escaping(Bool)->Void) {
|
init(account: Account, peerId: PeerId, searchMode: ChannelMembersSearchMode, openPeer: @escaping (Peer, RenderedChannelParticipant?) -> Void, cancel: @escaping () -> Void, updateActivity: @escaping(Bool) -> Void, present: @escaping (ViewController, Any?) -> Void) {
|
||||||
self.containerNode = ChannelMembersSearchContainerNode(account: account, peerId: peerId, mode: searchMode, filters: [], openPeer: { peer, participant in
|
self.containerNode = ChannelMembersSearchContainerNode(account: account, peerId: peerId, mode: searchMode, filters: [], openPeer: { peer, participant in
|
||||||
openPeer(peer, participant)
|
openPeer(peer, participant)
|
||||||
}, updateActivity: updateActivity)
|
}, updateActivity: updateActivity, present: present)
|
||||||
self.containerNode.cancel = {
|
self.containerNode.cancel = {
|
||||||
cancel()
|
cancel()
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user