Add peer categories in members lists

This commit is contained in:
Ilya Laktyushin 2022-01-23 03:22:19 +03:00
parent 47f3dde265
commit cc5de9372f
4 changed files with 228 additions and 71 deletions

View File

@ -7242,3 +7242,11 @@ Sorry for the inconvenience.";
"Conversation.CopyProtectionForwardingDisabledBot" = "Forwards from this bot are restricted";
"Conversation.CopyProtectionSavingDisabledBot" = "Saving from this bot is restricted";
"Channel.ChannelSubscribersHeader" = "CHANNEL SUBSCRIBERS";
"Channel.Members.Contacts" = "CONTACTS IN THIS CHANNEL";
"Channel.Members.Other" = "OTHERS SUBSCRIBERS";
"Group.Members.Contacts" = "CONTACTS IN THIS GROUP";
"Group.Members.Other" = "OTHERS MEMBERS";

View File

@ -26,6 +26,7 @@ public enum ChatListSearchItemHeaderType {
case activeVoiceChats
case recentCalls
case orImportIntoAnExistingGroup
case subscribers
fileprivate func title(strings: PresentationStrings) -> String {
switch self {
@ -71,6 +72,8 @@ public enum ChatListSearchItemHeaderType {
return strings.CallList_RecentCallsHeader
case .orImportIntoAnExistingGroup:
return strings.ChatList_HeaderImportIntoAnExistingGroup
case .subscribers:
return strings.Channel_ChannelSubscribersHeader
}
}
@ -118,6 +121,8 @@ public enum ChatListSearchItemHeaderType {
return .recentCalls
case .orImportIntoAnExistingGroup:
return .orImportIntoAnExistingGroup
case .subscribers:
return .subscribers
}
}
}
@ -148,6 +153,7 @@ private enum ChatListSearchItemHeaderId: Int32 {
case activeVoiceChats
case recentCalls
case orImportIntoAnExistingGroup
case subscribers
}
public final class ChatListSearchItemHeader: ListViewItemHeader {

View File

@ -36,6 +36,7 @@ private final class ChannelMembersControllerArguments {
private enum ChannelMembersSection: Int32 {
case addMembers
case contacts
case peers
}
@ -48,14 +49,20 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
case addMember(PresentationTheme, String)
case addMemberInfo(PresentationTheme, String)
case inviteLink(PresentationTheme, String)
case peerItem(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, RenderedChannelParticipant, ItemListPeerItemEditing, Bool)
case contactsTitle(PresentationTheme, String)
case peersTitle(PresentationTheme, String)
case peerItem(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, RenderedChannelParticipant, ItemListPeerItemEditing, Bool, Bool)
var section: ItemListSectionId {
switch self {
case .addMember, .addMemberInfo, .inviteLink:
return ChannelMembersSection.addMembers.rawValue
case .peerItem:
case .contactsTitle:
return ChannelMembersSection.contacts.rawValue
case .peersTitle:
return ChannelMembersSection.peers.rawValue
case let .peerItem(_, _, _, _, _, _, _, _, isContact):
return isContact ? ChannelMembersSection.contacts.rawValue : ChannelMembersSection.peers.rawValue
}
}
@ -65,9 +72,13 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
return .index(0)
case .addMemberInfo:
return .index(1)
case .inviteLink:
return .index(2)
case let .peerItem(_, _, _, _, _, participant, _, _):
case .inviteLink:
return .index(2)
case .contactsTitle:
return .index(3)
case .peersTitle:
return .index(4)
case let .peerItem(_, _, _, _, _, participant, _, _, _):
return .peer(participant.peer.id)
}
}
@ -86,14 +97,26 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
} else {
return false
}
case let .inviteLink(lhsTheme, lhsText):
if case let .inviteLink(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .peerItem(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsNameOrder, lhsParticipant, lhsEditing, lhsEnabled):
if case let .peerItem(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsNameOrder, rhsParticipant, rhsEditing, rhsEnabled) = rhs {
case let .inviteLink(lhsTheme, lhsText):
if case let .inviteLink(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .contactsTitle(lhsTheme, lhsText):
if case let .contactsTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .peersTitle(lhsTheme, lhsText):
if case let .peersTitle(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .peerItem(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsNameOrder, lhsParticipant, lhsEditing, lhsEnabled, lhsIsContact):
if case let .peerItem(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsNameOrder, rhsParticipant, rhsEditing, rhsEnabled, rhsIsContact) = rhs {
if lhsIndex != rhsIndex {
return false
}
@ -118,6 +141,9 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
if lhsEnabled != rhsEnabled {
return false
}
if lhsIsContact != rhsIsContact {
return false
}
return true
} else {
return false
@ -143,11 +169,30 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
default:
return true
}
case let .peerItem(index, _, _, _, _, _, _, _):
case .contactsTitle:
switch rhs {
case let .peerItem(rhsIndex, _, _, _, _, _, _, _):
return index < rhsIndex
case .addMember, .addMemberInfo, .inviteLink:
return false
default:
return true
}
case .peersTitle:
switch rhs {
case .addMember, .addMemberInfo, .inviteLink, .contactsTitle:
return false
case let .peerItem(_, _, _, _, _, _, _, _, isContact):
return !isContact
default:
return true
}
case let .peerItem(lhsIndex, _, _, _, _, _, _, _, lhsIsContact):
switch rhs {
case .contactsTitle:
return false
case .peersTitle:
return lhsIsContact
case let .peerItem(rhsIndex, _, _, _, _, _, _, _, _):
return lhsIndex < rhsIndex
case .addMember, .addMemberInfo, .inviteLink:
return false
}
@ -167,7 +212,9 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
})
case let .addMemberInfo(_, text):
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
case let .peerItem(_, _, strings, dateTimeFormat, nameDisplayOrder, participant, editing, enabled):
case let .contactsTitle(_, text), let .peersTitle(_, text):
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
case let .peerItem(_, _, strings, dateTimeFormat, nameDisplayOrder, participant, editing, enabled, _):
let text: ItemListPeerItemText
if let user = participant.peer as? TelegramUser, let _ = user.botInfo {
text = .text(strings.Bot_GenericBotStatus, .secondary)
@ -238,7 +285,7 @@ private struct ChannelMembersControllerState: Equatable {
}
}
private func channelMembersControllerEntries(context: AccountContext, presentationData: PresentationData, view: PeerView, state: ChannelMembersControllerState, participants: [RenderedChannelParticipant]?, isGroup: Bool) -> [ChannelMembersEntry] {
private func channelMembersControllerEntries(context: AccountContext, presentationData: PresentationData, view: PeerView, state: ChannelMembersControllerState, contacts: [RenderedChannelParticipant]?, participants: [RenderedChannelParticipant]?, isGroup: Bool) -> [ChannelMembersEntry] {
if participants == nil || participants?.count == nil {
return []
}
@ -251,6 +298,11 @@ private func channelMembersControllerEntries(context: AccountContext, presentati
canAddMember = peer.hasPermission(.inviteMembers)
}
var canEditMembers = false
if let peer = view.peers[view.peerId] as? TelegramChannel {
canEditMembers = peer.hasPermission(.banMembers)
}
if canAddMember {
entries.append(.addMember(presentationData.theme, isGroup ? presentationData.strings.Group_Members_AddMembers : presentationData.strings.Channel_Members_AddMembers))
if let peer = view.peers[view.peerId] as? TelegramChannel, peer.addressName == nil {
@ -267,14 +319,44 @@ private func channelMembersControllerEntries(context: AccountContext, presentati
var index: Int32 = 0
let sortedParticipants = participants
for participant in sortedParticipants {
var editable = true
var canEditMembers = false
if let peer = view.peers[view.peerId] as? TelegramChannel {
canEditMembers = peer.hasPermission(.banMembers)
var existingPeerIds = Set<PeerId>()
var addedContactsHeader = false
if let contacts = contacts, !contacts.isEmpty {
addedContactsHeader = true
entries.append(.contactsTitle(presentationData.theme, isGroup ? presentationData.strings.Group_Members_Contacts : presentationData.strings.Channel_Members_Contacts))
for participant in contacts {
var editable = true
if participant.peer.id == context.account.peerId {
editable = false
} else {
switch participant.participant {
case .creator:
editable = false
case .member:
editable = canEditMembers
}
}
entries.append(.peerItem(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, participant, ItemListPeerItemEditing(editable: editable, editing: state.editing, revealed: participant.peer.id == state.peerIdWithRevealedOptions), state.removingPeerId != participant.peer.id, true))
existingPeerIds.insert(participant.peer.id)
index += 1
}
}
var addedOtherHeader = false
for participant in participants {
if existingPeerIds.contains(participant.peer.id) {
continue
}
if addedContactsHeader && !addedOtherHeader {
addedOtherHeader = true
entries.append(.peersTitle(presentationData.theme, isGroup ? presentationData.strings.Group_Members_Other : presentationData.strings.Channel_Members_Other))
}
var editable = true
if participant.peer.id == context.account.peerId {
editable = false
} else {
@ -285,7 +367,7 @@ private func channelMembersControllerEntries(context: AccountContext, presentati
editable = canEditMembers
}
}
entries.append(.peerItem(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, participant, ItemListPeerItemEditing(editable: editable, editing: state.editing, revealed: participant.peer.id == state.peerIdWithRevealedOptions), state.removingPeerId != participant.peer.id))
entries.append(.peerItem(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, participant, ItemListPeerItemEditing(editable: editable, editing: state.editing, revealed: participant.peer.id == state.peerIdWithRevealedOptions), state.removingPeerId != participant.peer.id, false))
index += 1
}
}
@ -315,6 +397,7 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
actionsDisposable.add(removePeerDisposable)
let peersPromise = Promise<[RenderedChannelParticipant]?>(nil)
let contactsPromise = Promise<[RenderedChannelParticipant]?>(nil)
let arguments = ChannelMembersControllerArguments(context: context, addMember: {
actionsDisposable.add((peersPromise.get()
@ -437,17 +520,22 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
let peerView = context.account.viewTracker.peerView(peerId)
let (contactsDisposable, _) = context.peerChannelMemberCategoriesContextsManager.contacts(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: { state in
contactsPromise.set(.single(state.list))
})
let (disposable, loadMoreControl) = context.peerChannelMemberCategoriesContextsManager.recent(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, updated: { state in
peersPromise.set(.single(state.list))
})
actionsDisposable.add(disposable)
actionsDisposable.add(contactsDisposable)
var previousPeers: [RenderedChannelParticipant]?
var currentContacts: [RenderedChannelParticipant]?
var currentPeers: [RenderedChannelParticipant]?
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
let signal = combineLatest(queue: .mainQueue(), presentationData, statePromise.get(), peerView, peersPromise.get())
let signal = combineLatest(queue: .mainQueue(), presentationData, statePromise.get(), peerView, contactsPromise.get(), peersPromise.get())
|> deliverOnMainQueue
|> map { presentationData, state, view, peers -> (ItemListControllerState, (ItemListNodeState, Any)) in
|> map { presentationData, state, view, contacts, peers -> (ItemListControllerState, (ItemListNodeState, Any)) in
var isGroup = true
if let peer = peerViewMainPeer(view) as? TelegramChannel, case .broadcast = peer.info {
isGroup = false
@ -455,7 +543,14 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
var rightNavigationButton: ItemListNavigationButton?
var secondaryRightNavigationButton: ItemListNavigationButton?
if let peers = peers, !peers.isEmpty {
var isEmpty = true
if let contacts = contacts, !contacts.isEmpty {
isEmpty = false
} else if let peers = peers, !peers.isEmpty {
isEmpty = false
}
if !isEmpty {
if state.editing {
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: {
updateState { state in
@ -497,15 +592,26 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
}
var emptyStateItem: ItemListControllerEmptyStateItem?
if peers == nil || peers?.count == 0 {
if isEmpty {
emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme)
}
let previous = previousPeers
previousPeers = peers
let previousContacts = currentContacts
currentContacts = contacts
let previousPeers = currentPeers
currentPeers = peers
var animateChanges = false
if let previousContacts = previousContacts, let contacts = contacts, previousContacts.count >= contacts.count {
animateChanges = true
}
if let previousPeers = previousPeers, let peers = peers, previousPeers.count >= peers.count {
animateChanges = true
}
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(isGroup ? presentationData.strings.Group_Members_Title : presentationData.strings.Channel_Subscribers_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, secondaryRightNavigationButton: secondaryRightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelMembersControllerEntries(context: context, presentationData: presentationData, view: view, state: state, participants: peers, isGroup: isGroup), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: previous != nil && peers != nil && previous!.count >= peers!.count)
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelMembersControllerEntries(context: context, presentationData: presentationData, view: view, state: state, contacts: contacts, participants: peers, isGroup: isGroup), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: animateChanges)
return (controllerState, (listState, arguments))
}

View File

@ -38,14 +38,14 @@ private enum ChannelMembersSearchEntryId: Hashable {
private enum ChannelMembersSearchEntry: Comparable, Identifiable {
case copyInviteLink
case peer(Int, RenderedChannelParticipant, ContactsPeerItemEditing, String?, Bool)
case peer(Int, RenderedChannelParticipant, ContactsPeerItemEditing, String?, Bool, Bool, Bool)
case contact(Int, Peer, TelegramUserPresence?)
var stableId: ChannelMembersSearchEntryId {
switch self {
case .copyInviteLink:
return .copyInviteLink
case let .peer(_, participant, _, _, _):
case let .peer(_, participant, _, _, _, _, _):
return .peer(participant.peer.id)
case let .contact(_, peer, _):
return .contact(peer.id)
@ -60,8 +60,8 @@ private enum ChannelMembersSearchEntry: Comparable, Identifiable {
} else {
return false
}
case let .peer(lhsIndex, lhsParticipant, lhsEditing, lhsLabel, lhsEnabled):
if case .peer(lhsIndex, lhsParticipant, lhsEditing, lhsLabel, lhsEnabled) = rhs {
case let .peer(lhsIndex, lhsParticipant, lhsEditing, lhsLabel, lhsEnabled, lhsIsChannel, lhsIsContact):
if case .peer(lhsIndex, lhsParticipant, lhsEditing, lhsLabel, lhsEnabled, lhsIsChannel, lhsIsContact) = rhs {
return true
} else {
return false
@ -92,10 +92,10 @@ private enum ChannelMembersSearchEntry: Comparable, Identifiable {
} else {
return true
}
case let .peer(lhsIndex, _, _, _, _):
case let .peer(lhsIndex, _, _, _, _, _, _):
if case .copyInviteLink = rhs {
return false
} else if case let .peer(rhsIndex, _, _, _, _) = rhs {
} else if case let .peer(rhsIndex, _, _, _, _, _, _) = rhs {
return lhsIndex < rhsIndex
} else if case .contact = rhs {
return true
@ -127,7 +127,7 @@ private enum ChannelMembersSearchEntry: Comparable, Identifiable {
return ContactListActionItem(presentationData: ItemListPresentationData(presentationData), title: presentationData.strings.VoiceChat_CopyInviteLink, icon: icon, clearHighlightAutomatically: true, header: nil, action: {
interaction.copyInviteLink()
})
case let .peer(_, participant, editing, label, enabled):
case let .peer(_, participant, editing, label, enabled, isChannel, isContact):
let status: ContactsPeerItemStatus
if let label = label {
status = .custom(string: label, multiline: false)
@ -138,7 +138,14 @@ private enum ChannelMembersSearchEntry: Comparable, Identifiable {
status = .none
}
return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, peerMode: .peer, peer: .peer(peer: EnginePeer(participant.peer), chatPeer: nil), status: status, enabled: enabled, selection: .none, editing: editing, index: nil, header: ChatListSearchItemHeader(type: .groupMembers, theme: presentationData.theme, strings: presentationData.strings), action: { _ in
let headerType: ChatListSearchItemHeaderType
if isContact {
headerType = .contacts
} else {
headerType = isChannel ? .subscribers : .groupMembers
}
return ContactsPeerItem(presentationData: ItemListPresentationData(presentationData), sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, context: context, peerMode: .peer, peer: .peer(peer: EnginePeer(participant.peer), chatPeer: nil), status: status, enabled: enabled, selection: .none, editing: editing, index: nil, header: ChatListSearchItemHeader(type: headerType, theme: presentationData.theme, strings: presentationData.strings), action: { _ in
interaction.openPeer(participant.peer, participant)
})
case let .contact(_, peer, presence):
@ -239,6 +246,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
let previousEntries = Atomic<[ChannelMembersSearchEntry]?>(value: nil)
let disposableAndLoadMoreControl: (Disposable, PeerChannelMemberCategoryControl?)
let contactsDisposableAndLoadMoreControl: (Disposable, PeerChannelMemberCategoryControl?)?
let additionalDisposable = MetaDisposable()
if peerId.namespace == Namespaces.Peer.CloudGroup {
@ -398,7 +406,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: nil, banInfo: nil, rank: nil), peer: peer, peers: peers, presences: peerView.peerPresences)
}
entries.append(.peer(index, renderedParticipant, ContactsPeerItemEditing(editable: false, editing: false, revealed: false), label, enabled))
entries.append(.peer(index, renderedParticipant, ContactsPeerItemEditing(editable: false, editing: false, revealed: false), label, enabled, false, false))
index += 1
}
@ -420,6 +428,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
strongSelf.enqueueTransition(preparedTransition(from: previous, to: entries, context: context, presentationData: strongSelf.presentationData, nameSortOrder: strongSelf.presentationData.nameSortOrder, nameDisplayOrder: strongSelf.presentationData.nameDisplayOrder, interaction: interaction))
})
disposableAndLoadMoreControl = (disposable, nil)
contactsDisposableAndLoadMoreControl = nil
} else {
let membersState = Promise<ChannelMemberListState>()
@ -427,19 +436,26 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
membersState.set(.single(state))
})
let contactsState = Promise<ChannelMemberListState>()
contactsDisposableAndLoadMoreControl = context.peerChannelMemberCategoriesContextsManager.contacts(engine: context.engine, postbox: context.account.postbox, network: context.account.network, accountPeerId: context.account.peerId, peerId: peerId, searchQuery: nil, updated: { state in
contactsState.set(.single(state))
})
additionalDisposable.set((combineLatest(queue: .mainQueue(),
membersState.get(),
contactsState.get(),
context.account.postbox.peerView(id: peerId),
context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Contacts.List(includePresences: true)
)
).start(next: { [weak self] state, peerView, contactsView in
).start(next: { [weak self] state, contactsState, peerView, contactsView in
guard let strongSelf = self else {
return
}
var entries: [ChannelMembersSearchEntry] = []
var canInviteByLink = false
var isChannel = false
if let peer = peerViewMainPeer(peerView) {
if !(peer.addressName?.isEmpty ?? true) {
canInviteByLink = true
@ -447,6 +463,9 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
if peer.flags.contains(.isCreator) || (peer.adminRights?.rights.contains(.canInviteUsers) == true) {
canInviteByLink = true
}
if case .broadcast = peer.info {
isChannel = true
}
} else if let peer = peer as? TelegramGroup {
if case .creator = peer.role {
canInviteByLink = true
@ -456,6 +475,8 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
}
}
var index = 0
var existingPeersIds = Set<PeerId>()
if case .inviteToCall = mode, canInviteByLink, !filters.contains(where: { filter in
if case .excludeNonMembers = filter {
return true
@ -464,18 +485,53 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
}
}) {
entries.append(.copyInviteLink)
} else {
contactsLoop: for participant in contactsState.list {
if participant.peer.isDeleted {
continue contactsLoop
}
var label: String?
var enabled = true
for filter in filters {
switch filter {
case let .exclude(ids):
if ids.contains(participant.peer.id) {
continue contactsLoop
}
case let .disable(ids):
if ids.contains(participant.peer.id) {
enabled = false
}
case .excludeNonMembers:
break
case .excludeBots:
if let user = participant.peer as? TelegramUser, user.botInfo != nil {
continue contactsLoop
}
}
}
if case .promote = mode, case .creator = participant.participant {
label = strongSelf.presentationData.strings.Channel_Management_LabelOwner
enabled = false
}
entries.append(.peer(index, participant, ContactsPeerItemEditing(editable: false, editing: false, revealed: false), label, enabled, isChannel, true))
index += 1
existingPeersIds.insert(participant.peer.id)
}
}
var index = 0
participantsLoop: for participant in state.list {
if participant.peer.isDeleted {
if participant.peer.isDeleted || existingPeersIds.contains(participant.peer.id) {
continue participantsLoop
}
var label: String?
var enabled = true
switch mode {
case .ban:
case .ban, .promote:
if participant.peer.id == context.account.peerId {
continue participantsLoop
}
@ -497,29 +553,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
}
}
}
case .promote:
if participant.peer.id == context.account.peerId {
continue
}
for filter in filters {
switch filter {
case let .exclude(ids):
if ids.contains(participant.peer.id) {
continue participantsLoop
}
case let .disable(ids):
if ids.contains(participant.peer.id) {
enabled = false
}
case .excludeNonMembers:
break
case .excludeBots:
if let user = participant.peer as? TelegramUser, user.botInfo != nil {
continue participantsLoop
}
}
}
if case .creator = participant.participant {
if case .promote = mode, case .creator = participant.participant {
label = strongSelf.presentationData.strings.Channel_Management_LabelOwner
enabled = false
}
@ -549,7 +583,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
}
}
}
entries.append(.peer(index, participant, ContactsPeerItemEditing(editable: false, editing: false, revealed: false), label, enabled))
entries.append(.peer(index, participant, ContactsPeerItemEditing(editable: false, editing: false, revealed: false), label, enabled, isChannel, false))
index += 1
}
@ -575,6 +609,9 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
let combinedDisposable = DisposableSet()
combinedDisposable.add(disposableAndLoadMoreControl.0)
combinedDisposable.add(additionalDisposable)
if let disposable = contactsDisposableAndLoadMoreControl?.0 {
combinedDisposable.add(disposable)
}
self.disposable = combinedDisposable
self.listControl = disposableAndLoadMoreControl.1