[WIP] Topics

This commit is contained in:
Ali 2022-10-23 00:22:27 +04:00
parent 5ae5bbb2b8
commit 3ec3cce9c1
18 changed files with 165 additions and 102 deletions

View File

@ -2686,6 +2686,7 @@ Unused sets are archived when you add more.";
"Channel.AdminLog.PinMessages" = "Pin Messages";
"Channel.AdminLog.AddMembers" = "Add Members";
"Channel.AdminLog.SendPolls" = "Send Polls";
"Channel.AdminLog.ManageTopics" = "Manage Topics";
"Channel.AdminLog.CanChangeInfo" = "Change Info";
"Channel.AdminLog.CanSendMessages" = "Post Messages";
@ -2693,6 +2694,7 @@ Unused sets are archived when you add more.";
"Channel.AdminLog.CanBanUsers" = "Ban Users";
"Channel.AdminLog.CanInviteUsers" = "Add Users";
"Channel.AdminLog.CanPinMessages" = "Pin Messages";
"Channel.AdminLog.CanManageTopics" = "Manage Topics";
"Channel.AdminLog.CanAddAdmins" = "Add New Admins";
"Channel.AdminLog.CanBeAnonymous" = "Remain Anonymous";
"Channel.AdminLog.CanEditMessages" = "Edit Messages";
@ -3982,6 +3984,7 @@ Unused sets are archived when you add more.";
"GroupPermission.NoChangeInfo" = "no info";
"GroupPermission.NoAddMembers" = "no add";
"GroupPermission.NoPinMessages" = "no pin";
"GroupPermission.NoManageTopics" = "no topics";
"GroupPermission.Title" = "Exception";
"GroupPermission.NewTitle" = "New Exception";
@ -8137,7 +8140,7 @@ Sorry for the inconvenience.";
"ChatList.StartAction" = "Start";
"ChatList.CloseAction" = "Close";
"Channel.EditAdmin.PermissionCreateTopics" = "Create Topics";
"Channel.EditAdmin.PermissionManageTopics" = "Manage Topics";
"ChatList.Search.FilterTopics" = "Topics";
"DialogList.SearchSectionTopics" = "Topics";

View File

@ -509,7 +509,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
var items: [ContextMenuItem] = []
if channel.hasPermission(.pinMessages) {
if channel.hasPermission(.manageTopics) {
//TODO:localize
items.append(.action(ContextMenuActionItem(text: isPinned ? "Unpin" : "Pin", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin": "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.default)

View File

@ -2652,7 +2652,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
sourceController?.beginMessageSearch("")
})))
} else if channel.hasPermission(.pinMessages) {
} else if channel.hasPermission(.manageTopics) {
items.append(.separator)
//TODO:localize

View File

@ -2008,7 +2008,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
var canManage = false
if channel.flags.contains(.isCreator) {
canManage = true
} else if channel.adminRights != nil {
} else if channel.hasPermission(.pinMessages) {
canManage = true
} else if let threadInfo = threadInfo, threadInfo.isOwner {
canManage = true

View File

@ -438,11 +438,9 @@ private func stringForRight(strings: PresentationStrings, right: TelegramChatAdm
return strings.Channel_EditAdmin_PermissionInviteSubscribers
}
} else if right.contains(.canPinMessages) {
if isForum {
return strings.Channel_EditAdmin_PermissionCreateTopics
} else {
return strings.Channel_EditAdmin_PermissionPinMessages
}
return strings.Channel_EditAdmin_PermissionPinMessages
} else if right.contains(.canManageTopics) {
return strings.Channel_EditAdmin_PermissionManageTopics
} else if right.contains(.canAddAdmins) {
return strings.Channel_EditAdmin_PermissionAddAdmins
} else if right.contains(.canBeAnonymous) {
@ -530,12 +528,8 @@ private func rightEnabledByDefault(channelPeer: Peer, right: TelegramChatAdminRi
return false
}
private func areAllAdminRightsEnabled(_ flags: TelegramChatAdminRightsFlags, group: Bool, except: TelegramChatAdminRightsFlags) -> Bool {
if group {
return TelegramChatAdminRightsFlags.groupSpecific.subtracting(except).intersection(flags) == TelegramChatAdminRightsFlags.groupSpecific.subtracting(except)
} else {
return TelegramChatAdminRightsFlags.broadcastSpecific.subtracting(except).intersection(flags) == TelegramChatAdminRightsFlags.broadcastSpecific.subtracting(except)
}
private func areAllAdminRightsEnabled(_ flags: TelegramChatAdminRightsFlags, peer: EnginePeer, except: TelegramChatAdminRightsFlags) -> Bool {
return TelegramChatAdminRightsFlags.peerSpecific(peer: peer).subtracting(except).intersection(flags) == TelegramChatAdminRightsFlags.peerSpecific(peer: peer).subtracting(except)
}
private func channelAdminControllerEntries(presentationData: PresentationData, state: ChannelAdminControllerState, accountPeerId: PeerId, channelPeer: EnginePeer?, adminPeer: EnginePeer?, adminPresence: EnginePeer.Presence?, initialParticipant: ChannelParticipant?, invite: Bool, canEdit: Bool) -> [ChannelAdminEntry] {
@ -561,10 +555,10 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
var maskRightsFlags: TelegramChatAdminRightsFlags
let rightsOrder: [TelegramChatAdminRightsFlags]
maskRightsFlags = TelegramChatAdminRightsFlags.peerSpecific(peer: .channel(channel))
switch channel.info {
case .broadcast:
isGroup = false
maskRightsFlags = .broadcastSpecific
rightsOrder = [
.canChangeInfo,
.canPostMessages,
@ -576,17 +570,30 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
]
case .group:
isGroup = true
maskRightsFlags = .groupSpecific
rightsOrder = [
.canChangeInfo,
.canDeleteMessages,
.canBanUsers,
.canInviteUsers,
.canPinMessages,
.canManageCalls,
.canBeAnonymous,
.canAddAdmins
]
if channel.flags.contains(.isForum) {
rightsOrder = [
.canChangeInfo,
.canDeleteMessages,
.canBanUsers,
.canInviteUsers,
.canPinMessages,
.canManageTopics,
.canManageCalls,
.canBeAnonymous,
.canAddAdmins
]
} else {
rightsOrder = [
.canChangeInfo,
.canDeleteMessages,
.canBanUsers,
.canInviteUsers,
.canPinMessages,
.canManageCalls,
.canBeAnonymous,
.canAddAdmins
]
}
}
if isCreator {
@ -664,7 +671,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
entries.append(.addAdminsInfo(presentationData.theme, currentRightsFlags.contains(.canAddAdmins) ? presentationData.strings.Channel_EditAdmin_PermissinAddAdminOn : presentationData.strings.Channel_EditAdmin_PermissinAddAdminOff))
}
if case let .user(admin) = admin, admin.botInfo == nil && !admin.isDeleted && channel.flags.contains(.isCreator) && areAllAdminRightsEnabled(currentRightsFlags, group: isGroup, except: .canBeAnonymous) {
if case let .user(admin) = admin, admin.botInfo == nil && !admin.isDeleted && channel.flags.contains(.isCreator) && areAllAdminRightsEnabled(currentRightsFlags, peer: .channel(channel), except: .canBeAnonymous) {
canTransfer = true
}
@ -755,7 +762,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
let isGroup = true
let isChannel = false
let maskRightsFlags: TelegramChatAdminRightsFlags = .groupSpecific
let maskRightsFlags: TelegramChatAdminRightsFlags = TelegramChatAdminRightsFlags.peerSpecific(peer: .legacyGroup(group))
let rightsOrder: [TelegramChatAdminRightsFlags] = [
.canChangeInfo,
.canDeleteMessages,
@ -795,7 +802,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
entries.append(.addAdminsInfo(presentationData.theme, currentRightsFlags.contains(.canAddAdmins) ? presentationData.strings.Channel_EditAdmin_PermissinAddAdminOn : presentationData.strings.Channel_EditAdmin_PermissinAddAdminOff))
}
if case let .user(admin) = admin, case .creator = group.role, admin.botInfo == nil && !admin.isDeleted && areAllAdminRightsEnabled(currentRightsFlags, group: true, except: .canBeAnonymous) {
if case let .user(admin) = admin, case .creator = group.role, admin.botInfo == nil && !admin.isDeleted && areAllAdminRightsEnabled(currentRightsFlags, peer: .legacyGroup(group), except: .canBeAnonymous) {
entries.append(.transfer(presentationData.theme, presentationData.strings.Group_EditAdmin_TransferOwnership))
}
@ -1061,13 +1068,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
return
}
let maskRightsFlags: TelegramChatAdminRightsFlags
switch channel.info {
case .broadcast:
maskRightsFlags = .broadcastSpecific
case .group:
maskRightsFlags = .groupSpecific
}
let maskRightsFlags: TelegramChatAdminRightsFlags = TelegramChatAdminRightsFlags.peerSpecific(peer: .channel(channel))
var currentRank: String?
var currentFlags: TelegramChatAdminRightsFlags?
@ -1175,13 +1176,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
}
if updateFlags == nil {
let maskRightsFlags: TelegramChatAdminRightsFlags
switch channel.info {
case .broadcast:
maskRightsFlags = .broadcastSpecific
case .group:
maskRightsFlags = .groupSpecific
}
let maskRightsFlags: TelegramChatAdminRightsFlags = TelegramChatAdminRightsFlags.peerSpecific(peer: .channel(channel))
if channel.flags.contains(.isCreator) {
updateFlags = maskRightsFlags.subtracting([.canAddAdmins, .canBeAnonymous])
@ -1235,7 +1230,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
}))
}
}
} else if case .legacyGroup = channelPeer {
} else if case let .legacyGroup(group) = channelPeer {
var updateFlags: TelegramChatAdminRightsFlags?
var updateRank: String?
updateState { current in
@ -1251,7 +1246,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
return
}
let maskRightsFlags: TelegramChatAdminRightsFlags = .groupSpecific
let maskRightsFlags: TelegramChatAdminRightsFlags = TelegramChatAdminRightsFlags.peerSpecific(peer: .legacyGroup(group))
let defaultFlags = maskRightsFlags.subtracting([.canBeAnonymous, .canAddAdmins])
if updateFlags == nil {

View File

@ -681,7 +681,7 @@ public func channelAdminsController(context: AccountContext, updatedPresentation
var peers: [PeerId: Peer] = [:]
peers[creator.id] = creator
peers[peer.id] = peer
result.append(RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(rights: .groupSpecific), promotedBy: creator.id, canBeEditedByAccountPeer: creator.id == context.account.peerId), banInfo: nil, rank: nil), peer: peer, peers: peers))
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), peer: peer, peers: peers))
case .member:
break
}

View File

@ -291,7 +291,7 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation
entries.append(.rightsHeader(presentationData.theme, presentationData.strings.GroupPermission_SectionTitle))
var index = 0
for (right, _) in allGroupPermissionList {
for (right, _) in allGroupPermissionList(peer: .channel(channel)) {
let defaultEnabled = !defaultBannedRights.flags.contains(right) && channel.hasPermission(.banMembers)
entries.append(.rightItem(presentationData.theme, index, stringForGroupPermission(strings: presentationData.strings, right: right, isForum: channel.flags.contains(.isForum)), right, defaultEnabled && !currentRightsFlags.contains(right), defaultEnabled && !state.updating))
index += 1
@ -337,7 +337,7 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation
entries.append(.rightsHeader(presentationData.theme, presentationData.strings.GroupPermission_SectionTitle))
var index = 0
for (right, _) in allGroupPermissionList {
for (right, _) in allGroupPermissionList(peer: .legacyGroup(group)) {
let defaultEnabled = !defaultBannedRightsFlags.contains(right)
entries.append(.rightItem(presentationData.theme, index, stringForGroupPermission(strings: presentationData.strings, right: right, isForum: false), right, defaultEnabled && !currentRightsFlags.contains(right), defaultEnabled && !state.updating))
index += 1
@ -406,7 +406,7 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
effectiveRightsFlags = effectiveRightsFlags.subtracting(groupPermissionDependencies(rights))
} else {
effectiveRightsFlags.insert(rights)
for (right, _) in allGroupPermissionList {
for (right, _) in allGroupPermissionList(peer: EnginePeer(peer)) {
if groupPermissionDependencies(right).contains(rights) {
effectiveRightsFlags.insert(right)
}

View File

@ -826,7 +826,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
case let .member(_, _, _, banInfo, _):
if let banInfo = banInfo {
var exceptionsString = ""
for (rights, _) in allGroupPermissionList {
for (rights, _) in allGroupPermissionList(peer: .channel(channel)) {
if banInfo.rights.flags.contains(rights) {
if !exceptionsString.isEmpty {
exceptionsString.append(", ")
@ -930,7 +930,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
return entries
}
} else if let _ = peerView.peers[peerId] as? TelegramGroup, let cachedData = peerView.cachedData as? CachedGroupData {
} else if let group = peerView.peers[peerId] as? TelegramGroup, let cachedData = peerView.cachedData as? CachedGroupData {
updateActivity(true)
let foundGroupMembers: Signal<[RenderedChannelParticipant], NoError>
let foundMembers: Signal<[RenderedChannelParticipant], NoError>
@ -969,7 +969,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
peers[creator.id] = creator
}
peers[peer.id] = peer
renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(rights: .groupSpecific), promotedBy: creatorPeer?.id ?? context.account.peerId, canBeEditedByAccountPeer: creatorPeer?.id == context.account.peerId), banInfo: nil, rank: nil), peer: peer, peers: peers)
renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(rights: TelegramChatAdminRightsFlags.peerSpecific(peer: .legacyGroup(group))), promotedBy: creatorPeer?.id ?? context.account.peerId, canBeEditedByAccountPeer: creatorPeer?.id == context.account.peerId), banInfo: nil, rank: nil), peer: peer, peers: peers)
case .member:
var peers: [PeerId: Peer] = [:]
peers[peer.id] = peer
@ -1086,7 +1086,7 @@ public final class ChannelMembersSearchContainerNode: SearchDisplayControllerCon
case let .member(_, _, _, banInfo, _):
if let banInfo = banInfo {
var exceptionsString = ""
for (rights, _) in allGroupPermissionList {
for (rights, _) in allGroupPermissionList(peer: .legacyGroup(group)) {
if banInfo.rights.flags.contains(rights) {
if !exceptionsString.isEmpty {
exceptionsString.append(", ")

View File

@ -259,6 +259,9 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
guard let strongSelf = self else {
return
}
guard let mainPeer = peerViewMainPeer(peerView) else {
return
}
guard let cachedData = peerView.cachedData as? CachedGroupData, let participants = cachedData.participants else {
return
}
@ -279,19 +282,17 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
var entries: [ChannelMembersSearchEntry] = []
var canInviteByLink = false
if let peer = peerViewMainPeer(peerView) {
if !(peer.addressName?.isEmpty ?? true) {
if !(mainPeer.addressName?.isEmpty ?? true) {
canInviteByLink = true
} else if let peer = mainPeer as? TelegramChannel {
if peer.flags.contains(.isCreator) || (peer.adminRights?.rights.contains(.canInviteUsers) == true) {
canInviteByLink = true
}
} else if let peer = mainPeer as? TelegramGroup {
if case .creator = peer.role {
canInviteByLink = true
} else if case let .admin(rights, _) = peer.role, rights.rights.contains(.canInviteUsers) {
canInviteByLink = true
} else if let peer = peer as? TelegramChannel {
if peer.flags.contains(.isCreator) || (peer.adminRights?.rights.contains(.canInviteUsers) == true) {
canInviteByLink = true
}
} else if let peer = peer as? TelegramGroup {
if case .creator = peer.role {
canInviteByLink = true
} else if case let .admin(rights, _) = peer.role, rights.rights.contains(.canInviteUsers) {
canInviteByLink = true
}
}
}
@ -399,7 +400,7 @@ class ChannelMembersSearchControllerNode: ASDisplayNode {
var peers: [PeerId: Peer] = [:]
peers[creator.id] = creator
peers[peer.id] = peer
renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(rights: .groupSpecific), promotedBy: creator.id, canBeEditedByAccountPeer: creator.id == context.account.peerId), banInfo: nil, rank: nil), peer: peer, peers: peers, presences: peerView.peerPresences)
renderedParticipant = RenderedChannelParticipant(participant: .member(id: peer.id, invitedAt: 0, adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(rights: TelegramChatAdminRightsFlags.peerSpecific(peer: EnginePeer(mainPeer))), promotedBy: creator.id, canBeEditedByAccountPeer: creator.id == context.account.peerId), banInfo: nil, rank: nil), peer: peer, peers: peers, presences: peerView.peerPresences)
case .member:
var peers: [PeerId: Peer] = [:]
peers[peer.id] = peer

View File

@ -300,7 +300,7 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
case let .member(_, _, _, banInfo, _):
var exceptionsString = ""
if let banInfo = banInfo {
for (rights, _) in allGroupPermissionList {
for (rights, _) in internal_allPossibleGroupPermissionList {
if !defaultBannedRights.contains(rights) && banInfo.rights.flags.contains(rights) {
if !exceptionsString.isEmpty {
exceptionsString.append(", ")
@ -352,11 +352,9 @@ func stringForGroupPermission(strings: PresentationStrings, right: TelegramChatB
} else if right.contains(.banAddMembers) {
return strings.Channel_BanUser_PermissionAddMembers
} else if right.contains(.banPinMessages) {
if isForum {
return strings.Channel_EditAdmin_PermissionCreateTopics
} else {
return strings.Channel_EditAdmin_PermissionPinMessages
}
return strings.Channel_EditAdmin_PermissionPinMessages
} else if right.contains(.banManageTopics) {
return strings.Channel_EditAdmin_PermissionManageTopics
} else {
return ""
}
@ -379,12 +377,14 @@ func compactStringForGroupPermission(strings: PresentationStrings, right: Telegr
return strings.GroupPermission_NoAddMembers
} else if right.contains(.banPinMessages) {
return strings.GroupPermission_NoPinMessages
} else if right.contains(.banManageTopics) {
return strings.GroupPermission_NoManageTopics
} else {
return ""
}
}
public let allGroupPermissionList: [(TelegramChatBannedRightsFlags, TelegramChannelPermission)] = [
private let internal_allPossibleGroupPermissionList: [(TelegramChatBannedRightsFlags, TelegramChannelPermission)] = [
(.banSendMessages, .banMembers),
(.banSendMedia, .banMembers),
(.banSendGifs, .banMembers),
@ -392,9 +392,37 @@ public let allGroupPermissionList: [(TelegramChatBannedRightsFlags, TelegramChan
(.banSendPolls, .banMembers),
(.banAddMembers, .banMembers),
(.banPinMessages, .pinMessages),
(.banManageTopics, .manageTopics),
(.banChangeInfo, .changeInfo)
]
public func allGroupPermissionList(peer: EnginePeer) -> [(TelegramChatBannedRightsFlags, TelegramChannelPermission)] {
if case let .channel(channel) = peer, channel.flags.contains(.isForum) {
return [
(.banSendMessages, .banMembers),
(.banSendMedia, .banMembers),
(.banSendGifs, .banMembers),
(.banEmbedLinks, .banMembers),
(.banSendPolls, .banMembers),
(.banAddMembers, .banMembers),
(.banPinMessages, .pinMessages),
(.banManageTopics, .manageTopics),
(.banChangeInfo, .changeInfo)
]
} else {
return [
(.banSendMessages, .banMembers),
(.banSendMedia, .banMembers),
(.banSendGifs, .banMembers),
(.banEmbedLinks, .banMembers),
(.banSendPolls, .banMembers),
(.banAddMembers, .banMembers),
(.banPinMessages, .pinMessages),
(.banChangeInfo, .changeInfo)
]
}
}
let publicGroupRestrictedPermissions: TelegramChatBannedRightsFlags = [
.banPinMessages,
.banChangeInfo
@ -415,6 +443,8 @@ func groupPermissionDependencies(_ right: TelegramChatBannedRightsFlags) -> Tele
return []
} else if right.contains(.banPinMessages) {
return []
} else if right.contains(.banManageTopics) {
return []
} else {
return []
}
@ -433,7 +463,7 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
entries.append(.permissionsHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_SectionTitle))
var rightIndex: Int = 0
for (rights, correspondingAdminRight) in allGroupPermissionList {
for (rights, correspondingAdminRight) in allGroupPermissionList(peer: .channel(channel)) {
var enabled: Bool? = true
if channel.addressName != nil && publicGroupRestrictedPermissions.contains(rights) {
enabled = false
@ -482,7 +512,7 @@ private func channelPermissionsControllerEntries(context: AccountContext, presen
entries.append(.permissionsHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_SectionTitle))
var rightIndex: Int = 0
for (rights, _) in allGroupPermissionList {
for (rights, _) in allGroupPermissionList(peer: .legacyGroup(group)) {
entries.append(.permission(presentationData.theme, rightIndex, stringForGroupPermission(strings: presentationData.strings, right: rights, isForum: false), !effectiveRightsFlags.contains(rights), rights, true))
rightIndex += 1
}
@ -586,7 +616,7 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
effectiveRightsFlags = effectiveRightsFlags.subtracting(groupPermissionDependencies(rights))
} else {
effectiveRightsFlags.insert(rights)
for (right, _) in allGroupPermissionList {
for (right, _) in allGroupPermissionList(peer: .channel(channel)) {
if groupPermissionDependencies(right).contains(rights) {
effectiveRightsFlags.insert(right)
}
@ -616,7 +646,7 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
effectiveRightsFlags = effectiveRightsFlags.subtracting(groupPermissionDependencies(rights))
} else {
effectiveRightsFlags.insert(rights)
for (right, _) in allGroupPermissionList {
for (right, _) in allGroupPermissionList(peer: .legacyGroup(group)) {
if groupPermissionDependencies(right).contains(rights) {
effectiveRightsFlags.insert(right)
}
@ -718,7 +748,7 @@ public func channelPermissionsController(context: AccountContext, updatedPresent
guard let channel = view.peers[view.peerId] as? TelegramChannel else {
return
}
for (listRight, permission) in allGroupPermissionList {
for (listRight, permission) in allGroupPermissionList(peer: .channel(channel)) {
if listRight == right {
let text: String
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }

View File

@ -5,6 +5,7 @@ import Postbox
public enum TelegramChannelPermission {
case sendMessages
case pinMessages
case manageTopics
case inviteMembers
case editAllMessages
case deleteAllMessages
@ -66,6 +67,20 @@ public extension TelegramChannel {
}
return true
}
case .manageTopics:
if self.flags.contains(.isCreator) {
return true
}
if let adminRights = self.adminRights, adminRights.rights.contains(.canManageTopics) {
return true
}
if let bannedRights = self.bannedRights, bannedRights.flags.contains(.banManageTopics) {
return false
}
if let defaultBannedRights = self.defaultBannedRights, defaultBannedRights.flags.contains(.banManageTopics) {
return false
}
return true
case .inviteMembers:
if case .broadcast = self.info {
if let adminRights = self.adminRights {

View File

@ -226,10 +226,16 @@ func _internal_createForumChannelTopic(account: Account, peerId: PeerId, title:
}
if let topicId = topicId {
return resolveForumThreads(postbox: account.postbox, network: account.network, ids: [MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: topicId))])
return account.postbox.transaction { transaction -> Void in
transaction.removeHole(peerId: peerId, threadId: topicId, namespace: Namespaces.Message.Cloud, space: .everywhere, range: 1 ... (Int32.max - 1))
}
|> castError(CreateForumChannelTopicError.self)
|> map { _ -> Int64 in
return topicId
|> mapToSignal { _ -> Signal<Int64, CreateForumChannelTopicError> in
return resolveForumThreads(postbox: account.postbox, network: account.network, ids: [MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: Int32(clamping: topicId))])
|> castError(CreateForumChannelTopicError.self)
|> map { _ -> Int64 in
return topicId
}
}
} else {
return .fail(.generic)

View File

@ -21,17 +21,17 @@ public struct TelegramChatAdminRightsFlags: OptionSet, Hashable {
public static let canAddAdmins = TelegramChatAdminRightsFlags(rawValue: 1 << 9)
public static let canBeAnonymous = TelegramChatAdminRightsFlags(rawValue: 1 << 10)
public static let canManageCalls = TelegramChatAdminRightsFlags(rawValue: 1 << 11)
public static let canManageTopics = TelegramChatAdminRightsFlags(rawValue: 1 << 13)
public static var all: TelegramChatAdminRightsFlags {
return [.canChangeInfo, .canPostMessages, .canEditMessages, .canDeleteMessages, .canBanUsers, .canInviteUsers, .canPinMessages, .canAddAdmins, .canBeAnonymous, .canManageCalls]
return [.canChangeInfo, .canPostMessages, .canEditMessages, .canDeleteMessages, .canBanUsers, .canInviteUsers, .canPinMessages, .canAddAdmins, .canBeAnonymous, .canManageCalls, .canManageTopics]
}
public static var allChannel: TelegramChatAdminRightsFlags {
return [.canChangeInfo, .canPostMessages, .canEditMessages, .canDeleteMessages, .canBanUsers, .canInviteUsers, .canPinMessages, .canAddAdmins, .canManageCalls]
return [.canChangeInfo, .canPostMessages, .canEditMessages, .canDeleteMessages, .canBanUsers, .canInviteUsers, .canPinMessages, .canAddAdmins, .canManageCalls, .canManageTopics]
}
public static var groupSpecific: TelegramChatAdminRightsFlags = [
public static let internal_groupSpecific: TelegramChatAdminRightsFlags = [
.canChangeInfo,
.canDeleteMessages,
.canBanUsers,
@ -42,7 +42,7 @@ public struct TelegramChatAdminRightsFlags: OptionSet, Hashable {
.canAddAdmins
]
public static var broadcastSpecific: TelegramChatAdminRightsFlags = [
public static let internal_broadcastSpecific: TelegramChatAdminRightsFlags = [
.canChangeInfo,
.canPostMessages,
.canEditMessages,
@ -52,6 +52,20 @@ public struct TelegramChatAdminRightsFlags: OptionSet, Hashable {
.canAddAdmins
]
public static func peerSpecific(peer: EnginePeer) -> TelegramChatAdminRightsFlags {
if case let .channel(channel) = peer {
if channel.flags.contains(.isForum) {
return internal_groupSpecific.union(.canManageTopics)
} else if case .broadcast = channel.info {
return internal_broadcastSpecific
} else {
return internal_groupSpecific
}
} else {
return internal_groupSpecific
}
}
public var count: Int {
var result = 0
var index = 0

View File

@ -23,6 +23,7 @@ public struct TelegramChatBannedRightsFlags: OptionSet, Hashable {
public static let banChangeInfo = TelegramChatBannedRightsFlags(rawValue: 1 << 10)
public static let banAddMembers = TelegramChatBannedRightsFlags(rawValue: 1 << 15)
public static let banPinMessages = TelegramChatBannedRightsFlags(rawValue: 1 << 17)
public static let banManageTopics = TelegramChatBannedRightsFlags(rawValue: 1 << 18)
}
public struct TelegramChatBannedRights: PostboxCoding, Equatable {

View File

@ -83,12 +83,7 @@ func _internal_updateChannelOwnership(account: Account, accountStateManager: Acc
return account.postbox.transaction { transaction -> Signal<[(ChannelParticipant?, RenderedChannelParticipant)], ChannelOwnershipTransferError> in
if let channel = transaction.getPeer(channelId) as? TelegramChannel, let inputChannel = apiInputChannel(channel), let accountUser = transaction.getPeer(account.peerId), let user = transaction.getPeer(memberId), let inputUser = apiInputUser(user) {
var flags: TelegramChatAdminRightsFlags
if case .broadcast = channel.info {
flags = TelegramChatAdminRightsFlags.broadcastSpecific
} else {
flags = TelegramChatAdminRightsFlags.groupSpecific
}
let flags: TelegramChatAdminRightsFlags = TelegramChatAdminRightsFlags.peerSpecific(peer: .channel(channel))
let updatedParticipant = ChannelParticipant.creator(id: user.id, adminInfo: nil, rank: currentParticipant?.rank)
let updatedPreviousCreator = ChannelParticipant.member(id: accountUser.id, invitedAt: Int32(Date().timeIntervalSince1970), adminInfo: ChannelParticipantAdminInfo(rights: TelegramChatAdminRights(rights: flags), promotedBy: accountUser.id, canBeEditedByAccountPeer: false), banInfo: nil, rank: currentCreator?.rank)

View File

@ -663,6 +663,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
(.banSendPolls, self.presentationData.strings.Channel_AdminLog_SendPolls),
(.banAddMembers, self.presentationData.strings.Channel_AdminLog_AddMembers),
(.banPinMessages, self.presentationData.strings.Channel_AdminLog_PinMessages),
(.banManageTopics, self.presentationData.strings.Channel_AdminLog_ManageTopics),
(.banChangeInfo, self.presentationData.strings.Channel_AdminLog_ChangeInfo)
]
@ -792,8 +793,8 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
(.canAddAdmins, self.presentationData.strings.Channel_AdminLog_CanAddAdmins),
(.canManageCalls, self.presentationData.strings.Channel_AdminLog_CanManageLiveStreams)
]
prevFlags = prevFlags.intersection(TelegramChatAdminRightsFlags.broadcastSpecific)
newFlags = newFlags.intersection(TelegramChatAdminRightsFlags.broadcastSpecific)
prevFlags = prevFlags.intersection(TelegramChatAdminRightsFlags.peerSpecific(peer: EnginePeer(peer)))
newFlags = newFlags.intersection(TelegramChatAdminRightsFlags.peerSpecific(peer: EnginePeer(peer)))
} else {
order = [
(.canChangeInfo, self.presentationData.strings.Channel_AdminLog_CanChangeInfo),
@ -801,12 +802,13 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
(.canBanUsers, self.presentationData.strings.Channel_AdminLog_CanBanUsers),
(.canInviteUsers, self.presentationData.strings.Channel_AdminLog_CanInviteUsersViaLink),
(.canPinMessages, self.presentationData.strings.Channel_AdminLog_CanPinMessages),
(.canManageTopics, self.presentationData.strings.Channel_AdminLog_CanManageTopics),
(.canBeAnonymous, self.presentationData.strings.Channel_AdminLog_CanBeAnonymous),
(.canAddAdmins, self.presentationData.strings.Channel_AdminLog_CanAddAdmins),
(.canManageCalls, self.presentationData.strings.Channel_AdminLog_CanManageCalls)
]
prevFlags = prevFlags.intersection(TelegramChatAdminRightsFlags.groupSpecific)
newFlags = newFlags.intersection(TelegramChatAdminRightsFlags.groupSpecific)
prevFlags = prevFlags.intersection(TelegramChatAdminRightsFlags.peerSpecific(peer: EnginePeer(peer)))
newFlags = newFlags.intersection(TelegramChatAdminRightsFlags.peerSpecific(peer: EnginePeer(peer)))
}
if prevFlags.isEmpty && newFlags.isEmpty && (prevAdminRights != nil) != (newAdminRights != nil) {
@ -1016,6 +1018,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
(.banSendPolls, self.presentationData.strings.Channel_AdminLog_SendPolls),
(.banAddMembers, self.presentationData.strings.Channel_AdminLog_AddMembers),
(.banPinMessages, self.presentationData.strings.Channel_AdminLog_PinMessages),
(.banManageTopics, self.presentationData.strings.Channel_AdminLog_ManageTopics),
(.banChangeInfo, self.presentationData.strings.Channel_AdminLog_ChangeInfo)
]

View File

@ -932,7 +932,7 @@ func canEditPeerInfo(context: AccountContext, peer: Peer?, threadData: MessageHi
}
if let channel = peer as? TelegramChannel {
if let threadData = threadData {
if channel.hasPermission(.pinMessages) {
if channel.hasPermission(.manageTopics) {
return true
}
if threadData.author == context.account.peerId {

View File

@ -1654,7 +1654,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
var activePermissionCount: Int?
if let defaultBannedRights = channel.defaultBannedRights {
var count = 0
for (right, _) in allGroupPermissionList {
for (right, _) in allGroupPermissionList(peer: .channel(channel)) {
if !defaultBannedRights.flags.contains(right) {
count += 1
}
@ -1666,7 +1666,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
interaction.openParticipantsSection(.members)
}))
if !channel.flags.contains(.isGigagroup) {
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPermissions, label: .text(activePermissionCount.flatMap({ "\($0)/\(allGroupPermissionList.count)" }) ?? ""), text: presentationData.strings.GroupInfo_Permissions, icon: UIImage(bundleImageName: "Settings/Menu/SetPasscode"), action: {
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPermissions, label: .text(activePermissionCount.flatMap({ "\($0)/\(allGroupPermissionList(peer: .channel(channel)).count)" }) ?? ""), text: presentationData.strings.GroupInfo_Permissions, icon: UIImage(bundleImageName: "Settings/Menu/SetPasscode"), action: {
interaction.openPermissions()
}))
}
@ -1771,7 +1771,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
var activePermissionCount: Int?
if let defaultBannedRights = group.defaultBannedRights {
var count = 0
for (right, _) in allGroupPermissionList {
for (right, _) in allGroupPermissionList(peer: .legacyGroup(group)) {
if !defaultBannedRights.flags.contains(right) {
count += 1
}
@ -1779,7 +1779,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
activePermissionCount = count
}
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPermissions, label: .text(activePermissionCount.flatMap({ "\($0)/\(allGroupPermissionList.count)" }) ?? ""), text: presentationData.strings.GroupInfo_Permissions, icon: UIImage(bundleImageName: "Settings/Menu/SetPasscode"), action: {
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPermissions, label: .text(activePermissionCount.flatMap({ "\($0)/\(allGroupPermissionList(peer: .legacyGroup(group)).count)" }) ?? ""), text: presentationData.strings.GroupInfo_Permissions, icon: UIImage(bundleImageName: "Settings/Menu/SetPasscode"), action: {
interaction.openPermissions()
}))