Update hide members UI

This commit is contained in:
Ali 2022-12-17 00:17:47 +04:00
parent 614c74b0b0
commit 3981847514
2 changed files with 101 additions and 10 deletions

View File

@ -5,6 +5,7 @@ import AsyncDisplayKit
import SwiftSignalKit
import TelegramPresentationData
import SwitchNode
import AppBundle
public enum ItemListSwitchItemNodeType {
case regular
@ -19,6 +20,7 @@ public class ItemListSwitchItem: ListViewItem, ItemListItem {
let type: ItemListSwitchItemNodeType
let enableInteractiveChanges: Bool
let enabled: Bool
let displayLocked: Bool
let disableLeadingInset: Bool
let maximumNumberOfLines: Int
let noCorners: Bool
@ -28,7 +30,7 @@ public class ItemListSwitchItem: ListViewItem, ItemListItem {
let activatedWhileDisabled: () -> Void
public let tag: ItemListItemTag?
public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, title: String, value: Bool, type: ItemListSwitchItemNodeType = .regular, enableInteractiveChanges: Bool = true, enabled: Bool = true, disableLeadingInset: Bool = false, maximumNumberOfLines: Int = 1, noCorners: Bool = false, sectionId: ItemListSectionId, style: ItemListStyle, updated: @escaping (Bool) -> Void, activatedWhileDisabled: @escaping () -> Void = {}, tag: ItemListItemTag? = nil) {
public init(presentationData: ItemListPresentationData, icon: UIImage? = nil, title: String, value: Bool, type: ItemListSwitchItemNodeType = .regular, enableInteractiveChanges: Bool = true, enabled: Bool = true, displayLocked: Bool = false, disableLeadingInset: Bool = false, maximumNumberOfLines: Int = 1, noCorners: Bool = false, sectionId: ItemListSectionId, style: ItemListStyle, updated: @escaping (Bool) -> Void, activatedWhileDisabled: @escaping () -> Void = {}, tag: ItemListItemTag? = nil) {
self.presentationData = presentationData
self.icon = icon
self.title = title
@ -36,6 +38,7 @@ public class ItemListSwitchItem: ListViewItem, ItemListItem {
self.type = type
self.enableInteractiveChanges = enableInteractiveChanges
self.enabled = enabled
self.displayLocked = displayLocked
self.disableLeadingInset = disableLeadingInset
self.maximumNumberOfLines = maximumNumberOfLines
self.noCorners = noCorners
@ -128,6 +131,8 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
private let switchGestureNode: ASDisplayNode
private var disabledOverlayNode: ASDisplayNode?
private var lockedIconNode: ASImageNode?
private let activateArea: AccessibilityAreaNode
private var item: ItemListSwitchItem?
@ -405,6 +410,36 @@ public class ItemListSwitchItemNode: ListViewItemNode, ItemListItemNode {
}
strongSelf.switchGestureNode.isHidden = item.enableInteractiveChanges && item.enabled
if item.displayLocked {
var updateLockedIconImage = false
if let _ = updatedTheme {
updateLockedIconImage = true
}
let lockedIconNode: ASImageNode
if let current = strongSelf.lockedIconNode {
lockedIconNode = current
} else {
updateLockedIconImage = true
lockedIconNode = ASImageNode()
strongSelf.lockedIconNode = lockedIconNode
strongSelf.insertSubnode(lockedIconNode, aboveSubnode: strongSelf.switchNode)
}
if updateLockedIconImage, let image = generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/TextLockIcon"), color: item.presentationData.theme.list.itemSecondaryTextColor) {
lockedIconNode.image = image
}
let switchFrame = strongSelf.switchNode.frame
if let icon = lockedIconNode.image {
lockedIconNode.frame = CGRect(origin: CGPoint(x: switchFrame.minX + 10.0 + UIScreenPixel, y: switchFrame.minY + 9.0), size: icon.size)
}
} else if let lockedIconNode = strongSelf.lockedIconNode {
strongSelf.lockedIconNode = nil
lockedIconNode.removeFromSupernode()
}
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: 44.0 + UIScreenPixel + UIScreenPixel))
}
})

View File

@ -14,6 +14,7 @@ import PresentationDataUtils
import ItemListPeerItem
import ItemListPeerActionItem
import InviteLinksUI
import UndoUI
private final class ChannelMembersControllerArguments {
let context: AccountContext
@ -24,8 +25,9 @@ private final class ChannelMembersControllerArguments {
let openPeer: (Peer) -> Void
let inviteViaLink: () -> Void
let updateHideMembers: (Bool) -> Void
let displayHideMembersTip: (HideMembersDisabledReason) -> Void
init(context: AccountContext, addMember: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (Peer) -> Void, inviteViaLink: @escaping () -> Void, updateHideMembers: @escaping (Bool) -> Void) {
init(context: AccountContext, addMember: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (Peer) -> Void, inviteViaLink: @escaping () -> Void, updateHideMembers: @escaping (Bool) -> Void, displayHideMembersTip: @escaping (HideMembersDisabledReason) -> Void) {
self.context = context
self.addMember = addMember
self.setPeerIdWithRevealedOptions = setPeerIdWithRevealedOptions
@ -33,6 +35,7 @@ private final class ChannelMembersControllerArguments {
self.openPeer = openPeer
self.inviteViaLink = inviteViaLink
self.updateHideMembers = updateHideMembers
self.displayHideMembersTip = displayHideMembersTip
}
}
@ -48,8 +51,13 @@ private enum ChannelMembersEntryStableId: Hashable {
case peer(PeerId)
}
private enum HideMembersDisabledReason: Equatable {
case notEnoughMembers(Int)
case notAllowed
}
private enum ChannelMembersEntry: ItemListNodeEntry {
case hideMembers(String, Bool, Bool)
case hideMembers(text: String, disabledReason: HideMembersDisabledReason?, isInteractive: Bool, value: Bool)
case hideMembersInfo(String)
case addMember(PresentationTheme, String)
case addMemberInfo(PresentationTheme, String)
@ -96,8 +104,8 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
static func ==(lhs: ChannelMembersEntry, rhs: ChannelMembersEntry) -> Bool {
switch lhs {
case let .hideMembers(text, enabled, value):
if case .hideMembers(text, enabled, value) = rhs {
case let .hideMembers(text, enabled, isInteractive, value):
if case .hideMembers(text, enabled, isInteractive, value) = rhs {
return true
} else {
return false
@ -244,9 +252,17 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
let arguments = arguments as! ChannelMembersControllerArguments
switch self {
case let .hideMembers(text, enabled, value):
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enabled: enabled, sectionId: self.section, style: .blocks, updated: { value in
arguments.updateHideMembers(value)
case let .hideMembers(text, disabledReason, isInteractive, value):
return ItemListSwitchItem(presentationData: presentationData, title: text, value: value, enableInteractiveChanges: isInteractive, enabled: true, displayLocked: !value && disabledReason != nil, sectionId: self.section, style: .blocks, updated: { value in
if let disabledReason {
arguments.displayHideMembersTip(disabledReason)
} else {
arguments.updateHideMembers(value)
}
}, activatedWhileDisabled: {
if let disabledReason {
arguments.displayHideMembersTip(disabledReason)
}
})
case let .hideMembersInfo(text):
return ItemListTextItem(presentationData: presentationData, text: .markdown(text), sectionId: self.section)
@ -349,13 +365,33 @@ private func channelMembersControllerEntries(context: AccountContext, presentati
}
var membersHidden = false
var memberCount: Int?
if let cachedData = view.cachedData as? CachedChannelData, case let .known(value) = cachedData.membersHidden {
membersHidden = value.value
memberCount = cachedData.participantsSummary.memberCount.flatMap(Int.init)
}
if displayHideMembers {
let appConfiguration = context.currentAppConfiguration.with({ $0 })
var minMembers = 100
if let data = appConfiguration.data, let value = data["hidden_members_group_size_min"] as? Double {
minMembers = Int(value)
}
var disabledReason: HideMembersDisabledReason?
if memberCount ?? 0 < minMembers {
disabledReason = .notEnoughMembers(minMembers)
} else if !canSetupHideMembers {
disabledReason = .notAllowed
}
var isInteractive = canSetupHideMembers
if canSetupHideMembers && !membersHidden && disabledReason != nil {
isInteractive = false
}
//TODO:localize
entries.append(.hideMembers("Hide Members", canSetupHideMembers, membersHidden))
entries.append(.hideMembers(text: "Hide Members", disabledReason: disabledReason, isInteractive: isInteractive, value: membersHidden))
let infoText: String
if membersHidden {
@ -366,7 +402,7 @@ private func channelMembersControllerEntries(context: AccountContext, presentati
entries.append(.hideMembersInfo(infoText))
}
if !membersHidden, let participants = participants, let contacts = contacts {
if let participants = participants, let contacts = contacts {
var canAddMember: Bool = false
if let peer = view.peers[view.peerId] as? TelegramChannel {
canAddMember = peer.hasPermission(.inviteMembers)
@ -462,6 +498,8 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
var getControllerImpl: (() -> ViewController?)?
var displayHideMembersTip: ((HideMembersDisabledReason) -> Void)?
let actionsDisposable = DisposableSet()
let addMembersDisposable = MetaDisposable()
@ -592,6 +630,8 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
}
}, updateHideMembers: { value in
let _ = context.engine.peers.updateChannelMembersHidden(peerId: peerId, value: value).start()
}, displayHideMembersTip: { disabledReason in
displayHideMembersTip?(disabledReason)
})
let peerView = context.account.viewTracker.peerView(peerId)
@ -722,6 +762,22 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
dismissInputImpl = { [weak controller] in
controller?.view.endEditing(true)
}
displayHideMembersTip = { [weak controller] reason in
guard let controller else {
return
}
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
let text: String
switch reason {
case let .notEnoughMembers(minCount):
text = presentationData.strings.PeerInfo_HideMembersLimitedParticipantCountText(Int32(minCount))
case .notAllowed:
text = presentationData.strings.PeerInfo_HideMembersLimitedRights
}
controller.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_topics", scale: 0.066, colors: [:], title: nil, text: text, customUndoText: nil), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
}
getControllerImpl = { [weak controller] in
return controller
}