mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Group invitation sheet
This commit is contained in:
@@ -4,15 +4,50 @@ import SwiftSignalKit
|
||||
import TelegramApi
|
||||
import MtProtoKit
|
||||
|
||||
|
||||
public enum AddGroupMemberError {
|
||||
case generic
|
||||
case groupFull
|
||||
case privacy
|
||||
case privacy(TelegramInvitePeersResult?)
|
||||
case notMutualContact
|
||||
case tooManyChannels
|
||||
}
|
||||
|
||||
public final class TelegramForbiddenInvitePeer: Equatable {
|
||||
public let peer: EnginePeer
|
||||
public let canInviteWithPremium: Bool
|
||||
public let premiumRequiredToContact: Bool
|
||||
|
||||
public init(peer: EnginePeer, canInviteWithPremium: Bool, premiumRequiredToContact: Bool) {
|
||||
self.peer = peer
|
||||
self.canInviteWithPremium = canInviteWithPremium
|
||||
self.premiumRequiredToContact = premiumRequiredToContact
|
||||
}
|
||||
|
||||
public static func ==(lhs: TelegramForbiddenInvitePeer, rhs: TelegramForbiddenInvitePeer) -> Bool {
|
||||
if lhs === rhs {
|
||||
return true
|
||||
}
|
||||
if lhs.peer != rhs.peer {
|
||||
return false
|
||||
}
|
||||
if lhs.canInviteWithPremium != rhs.canInviteWithPremium {
|
||||
return false
|
||||
}
|
||||
if lhs.premiumRequiredToContact != rhs.premiumRequiredToContact {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
public final class TelegramInvitePeersResult {
|
||||
public let forbiddenPeers: [TelegramForbiddenInvitePeer]
|
||||
|
||||
public init(forbiddenPeers: [TelegramForbiddenInvitePeer]) {
|
||||
self.forbiddenPeers = forbiddenPeers
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_addGroupMember(account: Account, peerId: PeerId, memberId: PeerId) -> Signal<Void, AddGroupMemberError> {
|
||||
return account.postbox.transaction { transaction -> Signal<Void, AddGroupMemberError> in
|
||||
if let peer = transaction.getPeer(peerId), let memberPeer = transaction.getPeer(memberId), let inputUser = apiInputUser(memberPeer) {
|
||||
@@ -23,7 +58,7 @@ func _internal_addGroupMember(account: Account, peerId: PeerId, memberId: PeerId
|
||||
case "USERS_TOO_MUCH":
|
||||
return .groupFull
|
||||
case "USER_PRIVACY_RESTRICTED":
|
||||
return .privacy
|
||||
return .privacy(nil)
|
||||
case "USER_CHANNELS_TOO_MUCH":
|
||||
return .tooManyChannels
|
||||
case "USER_NOT_MUTUAL_CONTACT":
|
||||
@@ -34,14 +69,16 @@ func _internal_addGroupMember(account: Account, peerId: PeerId, memberId: PeerId
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Void, AddGroupMemberError> in
|
||||
let updatesValue: Api.Updates
|
||||
let missingInviteesValue: [Api.MissingInvitee]
|
||||
switch result {
|
||||
case let .invitedUsers(updates, missingInvitees):
|
||||
let _ = missingInvitees
|
||||
updatesValue = updates
|
||||
missingInviteesValue = missingInvitees
|
||||
}
|
||||
|
||||
account.stateManager.addUpdates(updatesValue)
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
|
||||
return account.postbox.transaction { transaction -> TelegramInvitePeersResult in
|
||||
if let message = updatesValue.messages.first, let timestamp = message.timestamp {
|
||||
transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in
|
||||
if let cachedData = cachedData as? CachedGroupData, let participants = cachedData.participants {
|
||||
@@ -62,8 +99,29 @@ func _internal_addGroupMember(account: Account, peerId: PeerId, memberId: PeerId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return TelegramInvitePeersResult(forbiddenPeers: missingInviteesValue.compactMap { invitee -> TelegramForbiddenInvitePeer? in
|
||||
switch invitee {
|
||||
case let .missingInvitee(flags, userId):
|
||||
guard let peer = transaction.getPeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))) else {
|
||||
return nil
|
||||
}
|
||||
return TelegramForbiddenInvitePeer(
|
||||
peer: EnginePeer(peer),
|
||||
canInviteWithPremium: (flags & (1 << 0)) != 0,
|
||||
premiumRequiredToContact: (flags & (1 << 1)) != 0
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|> mapError { _ -> AddGroupMemberError in }
|
||||
|> mapToSignal { result -> Signal<Void, AddGroupMemberError> in
|
||||
if result.forbiddenPeers.isEmpty {
|
||||
return .single(Void())
|
||||
} else {
|
||||
return .fail(.privacy(result))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return .fail(.generic)
|
||||
@@ -76,7 +134,7 @@ func _internal_addGroupMember(account: Account, peerId: PeerId, memberId: PeerId
|
||||
|
||||
public enum AddChannelMemberError {
|
||||
case generic
|
||||
case restricted
|
||||
case restricted(TelegramForbiddenInvitePeer?)
|
||||
case notMutualContact
|
||||
case limitExceeded
|
||||
case tooMuchJoined
|
||||
@@ -108,7 +166,7 @@ func _internal_addChannelMember(account: Account, peerId: PeerId, memberId: Peer
|
||||
case "USERS_TOO_MUCH":
|
||||
return .fail(.limitExceeded)
|
||||
case "USER_PRIVACY_RESTRICTED":
|
||||
return .fail(.restricted)
|
||||
return .fail(.restricted(nil))
|
||||
case "USER_NOT_MUTUAL_CONTACT":
|
||||
return .fail(.notMutualContact)
|
||||
case "USER_BOT":
|
||||
@@ -127,7 +185,14 @@ func _internal_addChannelMember(account: Account, peerId: PeerId, memberId: Peer
|
||||
let updatesValue: Api.Updates
|
||||
switch result {
|
||||
case let .invitedUsers(updates, missingInvitees):
|
||||
let _ = missingInvitees
|
||||
if case let .missingInvitee(flags, _) = missingInvitees.first {
|
||||
return .fail(.restricted(TelegramForbiddenInvitePeer(
|
||||
peer: EnginePeer(memberPeer),
|
||||
canInviteWithPremium: (flags & (1 << 0)) != 0,
|
||||
premiumRequiredToContact: (flags & (1 << 1)) != 0
|
||||
)))
|
||||
}
|
||||
|
||||
updatesValue = updates
|
||||
}
|
||||
|
||||
@@ -193,8 +258,8 @@ func _internal_addChannelMember(account: Account, peerId: PeerId, memberId: Peer
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_addChannelMembers(account: Account, peerId: PeerId, memberIds: [PeerId]) -> Signal<Void, AddChannelMemberError> {
|
||||
let signal = account.postbox.transaction { transaction -> Signal<Void, AddChannelMemberError> in
|
||||
func _internal_addChannelMembers(account: Account, peerId: PeerId, memberIds: [PeerId]) -> Signal<TelegramInvitePeersResult, AddChannelMemberError> {
|
||||
let signal = account.postbox.transaction { transaction -> Signal<TelegramInvitePeersResult, AddChannelMemberError> in
|
||||
var memberPeerIds: [PeerId:Peer] = [:]
|
||||
var inputUsers: [Api.InputUser] = []
|
||||
for memberId in memberIds {
|
||||
@@ -207,13 +272,13 @@ func _internal_addChannelMembers(account: Account, peerId: PeerId, memberIds: [P
|
||||
}
|
||||
|
||||
if let peer = transaction.getPeer(peerId), let channel = peer as? TelegramChannel, let inputChannel = apiInputChannel(channel) {
|
||||
let signal = account.network.request(Api.functions.channels.inviteToChannel(channel: inputChannel, users: inputUsers))
|
||||
let signal: Signal<TelegramInvitePeersResult, AddChannelMemberError> = account.network.request(Api.functions.channels.inviteToChannel(channel: inputChannel, users: inputUsers))
|
||||
|> mapError { error -> AddChannelMemberError in
|
||||
switch error.errorDescription {
|
||||
case "CHANNELS_TOO_MUCH":
|
||||
return .tooMuchJoined
|
||||
case "USER_PRIVACY_RESTRICTED":
|
||||
return .restricted
|
||||
return .restricted(nil)
|
||||
case "USER_NOT_MUTUAL_CONTACT":
|
||||
return .notMutualContact
|
||||
case "USERS_TOO_MUCH":
|
||||
@@ -224,21 +289,39 @@ func _internal_addChannelMembers(account: Account, peerId: PeerId, memberIds: [P
|
||||
return .generic
|
||||
}
|
||||
}
|
||||
|> map { result in
|
||||
|> mapToQueue { result -> Signal<TelegramInvitePeersResult, AddChannelMemberError> in
|
||||
let updatesValue: Api.Updates
|
||||
let missingInviteesValue: [Api.MissingInvitee]
|
||||
switch result {
|
||||
case let .invitedUsers(updates, missingInvitees):
|
||||
let _ = missingInvitees
|
||||
updatesValue = updates
|
||||
missingInviteesValue = missingInvitees
|
||||
}
|
||||
|
||||
account.stateManager.addUpdates(updatesValue)
|
||||
account.viewTracker.forceUpdateCachedPeerData(peerId: peerId)
|
||||
|
||||
return account.postbox.transaction { transaction -> TelegramInvitePeersResult in
|
||||
return TelegramInvitePeersResult(forbiddenPeers: missingInviteesValue.compactMap { invitee -> TelegramForbiddenInvitePeer? in
|
||||
switch invitee {
|
||||
case let .missingInvitee(flags, userId):
|
||||
guard let peer = transaction.getPeer(PeerId(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(userId))) else {
|
||||
return nil
|
||||
}
|
||||
return TelegramForbiddenInvitePeer(
|
||||
peer: EnginePeer(peer),
|
||||
canInviteWithPremium: (flags & (1 << 0)) != 0,
|
||||
premiumRequiredToContact: (flags & (1 << 1)) != 0
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|> castError(AddChannelMemberError.self)
|
||||
}
|
||||
|
||||
return signal
|
||||
} else {
|
||||
return .single(Void())
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user