mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
Update hide members UI
This commit is contained in:
parent
614c74b0b0
commit
3981847514
@ -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))
|
||||
}
|
||||
})
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user