Various improvements

This commit is contained in:
Ilya Laktyushin 2026-02-24 03:03:45 +04:00
parent e3cbd92a40
commit b07a2fbb77
2 changed files with 49 additions and 40 deletions

View file

@ -2,6 +2,7 @@ import Foundation
import UIKit
import Display
import SwiftSignalKit
import Postbox
import TelegramCore
import TelegramPresentationData
import TelegramUIPreferences
@ -860,22 +861,27 @@ public func channelAdminsController(context: AccountContext, updatedPresentation
return context.engine.data.subscribe(
TelegramEngine.EngineData.Item.Peer.LegacyGroupParticipants(id: peerId)
)
|> mapToSignal { participants -> Signal<[(EngineLegacyGroupParticipant, EnginePeer?)]?, NoError> in
|> mapToSignal { participants -> Signal<[(EngineLegacyGroupParticipant, EnginePeer?, EnginePeer.Presence?)]?, NoError> in
guard case let .known(participants) = participants else {
return .single(nil)
}
return context.engine.data.subscribe(
EngineDataMap(participants.map { TelegramEngine.EngineData.Item.Peer.Peer(id: $0.peerId) })
EngineDataMap(participants.map { TelegramEngine.EngineData.Item.Peer.Peer(id: $0.peerId) }),
EngineDataMap(participants.map { TelegramEngine.EngineData.Item.Peer.Presence(id: $0.peerId) })
)
|> map { peers -> [(EngineLegacyGroupParticipant, EnginePeer?)]? in
var result: [(EngineLegacyGroupParticipant, EnginePeer?)] = []
|> map { peers, presences -> [(EngineLegacyGroupParticipant, EnginePeer?, EnginePeer.Presence?)]? in
var result: [(EngineLegacyGroupParticipant, EnginePeer?, EnginePeer.Presence?)] = []
for participant in participants {
var peer: EnginePeer?
var presence: EnginePeer.Presence?
if let peerValue = peers[participant.peerId] {
peer = peerValue
}
result.append((participant, peer))
if let presenceValue = presences[participant.peerId] {
presence = presenceValue
}
result.append((participant, peer, presence))
}
return result
}
@ -887,7 +893,7 @@ public func channelAdminsController(context: AccountContext, updatedPresentation
var result: [RenderedChannelParticipant] = []
var creatorPeer: EnginePeer?
for (participant, peer) in participants {
for (participant, peer, _) in participants {
if let peer {
switch participant {
case .creator:
@ -900,16 +906,20 @@ public func channelAdminsController(context: AccountContext, updatedPresentation
guard let creator = creatorPeer else {
return nil
}
for (participant, peer) in participants {
for (participant, peer, presence) in participants {
if let peer {
var presences: [PeerId: PeerPresence] = [:]
if let presence {
presences[peer.id] = presence._asPresence()
}
switch participant {
case .creator:
result.append(RenderedChannelParticipant(participant: .creator(id: peer.id, adminInfo: nil, rank: nil), peer: peer._asPeer()))
case .admin:
case let .creator(_, rank):
result.append(RenderedChannelParticipant(participant: .creator(id: peer.id, adminInfo: nil, rank: rank), peer: peer._asPeer(), presences: presences))
case let .admin(_, _, _, rank):
var peers: [EnginePeer.Id: EnginePeer] = [:]
peers[creator.id] = creator
peers[peer.id] = peer
result.append(RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(rights: .internal_groupSpecific), promotedBy: creator.id, canBeEditedByAccountPeer: creator.id == context.account.peerId), banInfo: nil, rank: nil, subscriptionUntilDate: nil), peer: peer._asPeer(), peers: peers.mapValues({ $0._asPeer() })))
result.append(RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(rights: .internal_groupSpecific), promotedBy: creator.id, canBeEditedByAccountPeer: creator.id == context.account.peerId), banInfo: nil, rank: rank, subscriptionUntilDate: nil), peer: peer._asPeer(), peers: peers.mapValues({ $0._asPeer() }), presences: presences))
case .member:
break
}

View file

@ -23,7 +23,7 @@ private final class ChannelMembersControllerArguments {
let addMember: () -> Void
let setPeerIdWithRevealedOptions: (EnginePeer.Id?, EnginePeer.Id?) -> Void
let removePeer: (EnginePeer.Id) -> Void
let openParticipant: (RenderedChannelParticipant) -> Void
let openParticipant: (RenderedChannelParticipant, Bool) -> Void
let inviteViaLink: () -> Void
let updateHideMembers: (Bool) -> Void
let displayHideMembersTip: (HideMembersDisabledReason) -> Void
@ -33,7 +33,7 @@ private final class ChannelMembersControllerArguments {
addMember: @escaping () -> Void,
setPeerIdWithRevealedOptions: @escaping (EnginePeer.Id?, EnginePeer.Id?) -> Void,
removePeer: @escaping (EnginePeer.Id) -> Void,
openParticipant: @escaping (RenderedChannelParticipant) -> Void,
openParticipant: @escaping (RenderedChannelParticipant, Bool) -> Void,
inviteViaLink: @escaping () -> Void,
updateHideMembers: @escaping (Bool) -> Void,
displayHideMembersTip: @escaping (HideMembersDisabledReason) -> Void
@ -74,7 +74,7 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
case inviteLink(PresentationTheme, String)
case contactsTitle(PresentationTheme, String)
case peersTitle(PresentationTheme, String)
case peerItem(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, RenderedChannelParticipant, ItemListPeerItemEditing, Bool, Bool)
case peerItem(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, RenderedChannelParticipant, ItemListPeerItemEditing, Bool, Bool, Bool)
var section: ItemListSectionId {
switch self {
@ -86,7 +86,7 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
return ChannelMembersSection.contacts.rawValue
case .peersTitle:
return ChannelMembersSection.peers.rawValue
case let .peerItem(_, _, _, _, _, _, _, _, isContact):
case let .peerItem(_, _, _, _, _, _, _, _, isContact, _):
return isContact ? ChannelMembersSection.contacts.rawValue : ChannelMembersSection.peers.rawValue
}
}
@ -107,7 +107,7 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
return .index(7)
case .peersTitle:
return .index(8)
case let .peerItem(_, _, _, _, _, participant, _, _, _):
case let .peerItem(_, _, _, _, _, participant, _, _, _, _):
return .peer(participant.peer.id)
}
}
@ -156,8 +156,8 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
} 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 {
case let .peerItem(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsNameOrder, lhsParticipant, lhsEditing, lhsEnabled, lhsIsContact, lhsIsGroup):
if case let .peerItem(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsNameOrder, rhsParticipant, rhsEditing, rhsEnabled, rhsIsContact, rhsIsGroup) = rhs {
if lhsIndex != rhsIndex {
return false
}
@ -185,6 +185,9 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
if lhsIsContact != rhsIsContact {
return false
}
if lhsIsGroup != rhsIsGroup {
return false
}
return true
} else {
return false
@ -240,18 +243,18 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
switch rhs {
case .hideMembers, .hideMembersInfo, .addMember, .addMemberInfo, .inviteLink, .contactsTitle:
return false
case let .peerItem(_, _, _, _, _, _, _, _, isContact):
case let .peerItem(_, _, _, _, _, _, _, _, isContact, _):
return !isContact
default:
return true
}
case let .peerItem(lhsIndex, _, _, _, _, _, _, _, lhsIsContact):
case let .peerItem(lhsIndex, _, _, _, _, _, _, _, lhsIsContact, _):
switch rhs {
case .contactsTitle:
return false
case .peersTitle:
return lhsIsContact
case let .peerItem(rhsIndex, _, _, _, _, _, _, _, _):
case let .peerItem(rhsIndex, _, _, _, _, _, _, _, _, _):
return lhsIndex < rhsIndex
case .hideMembers, .hideMembersInfo, .addMember, .addMemberInfo, .inviteLink:
return false
@ -288,7 +291,7 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
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, _):
case let .peerItem(_, _, strings, dateTimeFormat, nameDisplayOrder, participant, editing, enabled, _, isGroup):
let text: ItemListPeerItemText
if let user = participant.peer as? TelegramUser, let _ = user.botInfo {
text = .text(strings.Bot_GenericBotStatus, .secondary)
@ -319,7 +322,7 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
}
return ItemListPeerItem(presentationData: presentationData, systemStyle: .glass, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: EnginePeer(participant.peer), presence: participant.presences[participant.peer.id].flatMap(EnginePeer.Presence.init), text: text, label: label, editing: editing, switchValue: nil, enabled: enabled, selectable: participant.peer.id != arguments.context.account.peerId, sectionId: self.section, action: {
arguments.openParticipant(participant)
arguments.openParticipant(participant, isGroup)
}, setPeerIdWithRevealedOptions: { previousId, id in
arguments.setPeerIdWithRevealedOptions(previousId, id)
}, removePeer: { peerId in
@ -480,7 +483,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, true))
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, isGroup))
existingPeerIds.insert(participant.peer.id)
index += 1
}
@ -508,7 +511,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, false))
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, isGroup))
index += 1
}
}
@ -680,10 +683,16 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
return $0.withUpdatedRemovingPeerId(nil)
}
}))
}, openParticipant: { participant in
let controller = channelBannedMemberController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, memberId: participant.peer.id, editMember: true, initialParticipant: participant.participant, updated: { rights in
}, upgradedToSupergroup: { _, _ in })
pushControllerImpl?(controller)
}, openParticipant: { participant, isGroup in
if isGroup {
let controller = channelBannedMemberController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, memberId: participant.peer.id, editMember: true, initialParticipant: participant.participant, updated: { rights in
}, upgradedToSupergroup: { _, _ in })
pushControllerImpl?(controller)
} else {
if let infoController = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: participant.peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
pushControllerImpl?(infoController)
}
}
}, inviteViaLink: {
if let controller = getControllerImpl?() {
dismissInputImpl?()
@ -789,17 +798,7 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
}
}
var title: String = isGroup ? presentationData.strings.Group_Members_Title : presentationData.strings.Channel_Subscribers_Title
if let cachedData = view.cachedData as? CachedGroupData {
if let count = cachedData.participants?.participants.count {
title = presentationData.strings.GroupInfo_TitleMembers(Int32(count))
}
} else if let cachedData = view.cachedData as? CachedChannelData {
if let count = cachedData.participantsSummary.memberCount {
title = presentationData.strings.GroupInfo_TitleMembers(count)
}
}
let title: String = isGroup ? presentationData.strings.Group_Members_Title : presentationData.strings.Channel_Subscribers_Title
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(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, contacts: contacts, participants: peers, isGroup: isGroup), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: animateChanges)