mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
[WIP] Folders
This commit is contained in:
@@ -15,15 +15,28 @@ public struct ExportedChatFolderLink: Equatable {
|
||||
public var title: String
|
||||
public var link: String
|
||||
public var peerIds: [EnginePeer.Id]
|
||||
public var isRevoked: Bool
|
||||
|
||||
public init(
|
||||
title: String,
|
||||
link: String,
|
||||
peerIds: [EnginePeer.Id]
|
||||
peerIds: [EnginePeer.Id],
|
||||
isRevoked: Bool
|
||||
) {
|
||||
self.title = title
|
||||
self.link = link
|
||||
self.peerIds = peerIds
|
||||
self.isRevoked = isRevoked
|
||||
}
|
||||
}
|
||||
|
||||
public extension ExportedChatFolderLink {
|
||||
var slug: String {
|
||||
var slug = self.link
|
||||
if slug.hasPrefix("https://t.me/folder/") {
|
||||
slug = String(slug[slug.index(slug.startIndex, offsetBy: "https://t.me/folder/".count)...])
|
||||
}
|
||||
return slug
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,11 +68,12 @@ func _internal_exportChatFolder(account: Account, filterId: Int32, title: String
|
||||
})
|
||||
|
||||
switch invite {
|
||||
case let .exportedCommunityInvite(title, url, peers):
|
||||
case let .exportedCommunityInvite(flags, title, url, peers):
|
||||
return .single(ExportedChatFolderLink(
|
||||
title: title,
|
||||
link: url,
|
||||
peerIds: peers.map(\.peerId)
|
||||
peerIds: peers.map(\.peerId),
|
||||
isRevoked: (flags & (1 << 0)) != 0
|
||||
))
|
||||
}
|
||||
}
|
||||
@@ -70,7 +84,7 @@ func _internal_exportChatFolder(account: Account, filterId: Int32, title: String
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_getExportedChatLinks(account: Account, id: Int32) -> Signal<[ExportedChatFolderLink], NoError> {
|
||||
func _internal_getExportedChatFolderLinks(account: Account, id: Int32) -> Signal<[ExportedChatFolderLink], NoError> {
|
||||
return account.network.request(Api.functions.communities.getExportedInvites(community: .inputCommunityDialogFilter(filterId: id)))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.communities.ExportedInvites?, NoError> in
|
||||
@@ -105,8 +119,13 @@ func _internal_getExportedChatLinks(account: Account, id: Int32) -> Signal<[Expo
|
||||
var result: [ExportedChatFolderLink] = []
|
||||
for invite in invites {
|
||||
switch invite {
|
||||
case let .exportedCommunityInvite(title, url, peers):
|
||||
result.append(ExportedChatFolderLink(title: title, link: url, peerIds: peers.map(\.peerId)))
|
||||
case let .exportedCommunityInvite(flags, title, url, peers):
|
||||
result.append(ExportedChatFolderLink(
|
||||
title: title,
|
||||
link: url,
|
||||
peerIds: peers.map(\.peerId),
|
||||
isRevoked: (flags & (1 << 0)) != 0
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,3 +134,171 @@ func _internal_getExportedChatLinks(account: Account, id: Int32) -> Signal<[Expo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum EditChatFolderLinkError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_editChatFolderLink(account: Account, filterId: Int32, link: ExportedChatFolderLink, title: String?, revoke: Bool) -> Signal<Never, EditChatFolderLinkError> {
|
||||
var flags: Int32 = 0
|
||||
if revoke {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
if title != nil {
|
||||
flags |= 1 << 1
|
||||
}
|
||||
return account.network.request(Api.functions.communities.editExportedInvite(flags: flags, community: .inputCommunityDialogFilter(filterId: filterId), slug: link.slug, title: title))
|
||||
|> mapError { _ -> EditChatFolderLinkError in
|
||||
return .generic
|
||||
}
|
||||
|> ignoreValues
|
||||
|
||||
}
|
||||
|
||||
public enum RevokeChatFolderLinkError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_revokeChatFolderLink(account: Account, filterId: Int32, link: ExportedChatFolderLink) -> Signal<Never, RevokeChatFolderLinkError> {
|
||||
return account.network.request(Api.functions.communities.deleteExportedInvite(community: .inputCommunityDialogFilter(filterId: filterId), slug: link.slug))
|
||||
|> mapError { _ -> RevokeChatFolderLinkError in
|
||||
return .generic
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
|
||||
public enum CheckChatFolderLinkError {
|
||||
case generic
|
||||
}
|
||||
|
||||
public final class ChatFolderLinkContents {
|
||||
public let localFilterId: Int32?
|
||||
public let title: String?
|
||||
public let peers: [EnginePeer]
|
||||
public let alreadyMemberPeerIds: Set<EnginePeer.Id>
|
||||
|
||||
public init(
|
||||
localFilterId: Int32?,
|
||||
title: String?,
|
||||
peers: [EnginePeer],
|
||||
alreadyMemberPeerIds: Set<EnginePeer.Id>
|
||||
) {
|
||||
self.localFilterId = localFilterId
|
||||
self.title = title
|
||||
self.peers = peers
|
||||
self.alreadyMemberPeerIds = alreadyMemberPeerIds
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_checkChatFolderLink(account: Account, slug: String) -> Signal<ChatFolderLinkContents, CheckChatFolderLinkError> {
|
||||
return account.network.request(Api.functions.communities.checkCommunityInvite(slug: slug))
|
||||
|> mapError { _ -> CheckChatFolderLinkError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { result -> Signal<ChatFolderLinkContents, CheckChatFolderLinkError> in
|
||||
return account.postbox.transaction { transaction -> ChatFolderLinkContents in
|
||||
switch result {
|
||||
case let .communityInvite(title, peers, chats, users):
|
||||
var allPeers: [Peer] = []
|
||||
var peerPresences: [PeerId: Api.User] = [:]
|
||||
|
||||
for user in users {
|
||||
let telegramUser = TelegramUser(user: user)
|
||||
allPeers.append(telegramUser)
|
||||
peerPresences[telegramUser.id] = user
|
||||
}
|
||||
for chat in chats {
|
||||
if let peer = parseTelegramGroupOrChannel(chat: chat) {
|
||||
allPeers.append(peer)
|
||||
}
|
||||
}
|
||||
|
||||
updatePeers(transaction: transaction, peers: allPeers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences)
|
||||
|
||||
var resultPeers: [EnginePeer] = []
|
||||
var alreadyMemberPeerIds = Set<EnginePeer.Id>()
|
||||
for peer in peers {
|
||||
if let peerValue = transaction.getPeer(peer.peerId) {
|
||||
resultPeers.append(EnginePeer(peerValue))
|
||||
|
||||
if transaction.getPeerChatListIndex(peer.peerId) != nil {
|
||||
alreadyMemberPeerIds.insert(peer.peerId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ChatFolderLinkContents(localFilterId: nil, title: title, peers: resultPeers, alreadyMemberPeerIds: alreadyMemberPeerIds)
|
||||
case let .communityInviteAlready(filterId, missingPeers, chats, users):
|
||||
var allPeers: [Peer] = []
|
||||
var peerPresences: [PeerId: Api.User] = [:]
|
||||
|
||||
for user in users {
|
||||
let telegramUser = TelegramUser(user: user)
|
||||
allPeers.append(telegramUser)
|
||||
peerPresences[telegramUser.id] = user
|
||||
}
|
||||
for chat in chats {
|
||||
if let peer = parseTelegramGroupOrChannel(chat: chat) {
|
||||
allPeers.append(peer)
|
||||
}
|
||||
}
|
||||
|
||||
updatePeers(transaction: transaction, peers: allPeers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences)
|
||||
|
||||
let currentFilters = _internal_currentChatListFilters(transaction: transaction)
|
||||
var currentFilterTitle: String?
|
||||
if let index = currentFilters.firstIndex(where: { $0.id == filterId }) {
|
||||
switch currentFilters[index] {
|
||||
case let .filter(_, title, _, _):
|
||||
currentFilterTitle = title
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
var resultPeers: [EnginePeer] = []
|
||||
var alreadyMemberPeerIds = Set<EnginePeer.Id>()
|
||||
for peer in missingPeers {
|
||||
if let peerValue = transaction.getPeer(peer.peerId) {
|
||||
resultPeers.append(EnginePeer(peerValue))
|
||||
|
||||
if transaction.getPeerChatListIndex(peer.peerId) != nil {
|
||||
alreadyMemberPeerIds.insert(peer.peerId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ChatFolderLinkContents(localFilterId: filterId, title: currentFilterTitle, peers: resultPeers, alreadyMemberPeerIds: alreadyMemberPeerIds)
|
||||
}
|
||||
}
|
||||
|> castError(CheckChatFolderLinkError.self)
|
||||
}
|
||||
}
|
||||
|
||||
public enum JoinChatFolderLinkError {
|
||||
case generic
|
||||
}
|
||||
|
||||
func _internal_joinChatFolderLink(account: Account, slug: String, peerIds: [EnginePeer.Id]) -> Signal<Never, JoinChatFolderLinkError> {
|
||||
return account.postbox.transaction { transaction -> [Api.InputPeer] in
|
||||
return peerIds.compactMap(transaction.getPeer).compactMap(apiInputPeer)
|
||||
}
|
||||
|> castError(JoinChatFolderLinkError.self)
|
||||
|> mapToSignal { inputPeers -> Signal<Never, JoinChatFolderLinkError> in
|
||||
return account.network.request(Api.functions.communities.joinCommunityInvite(slug: slug, peers: inputPeers))
|
||||
|> mapError { _ -> JoinChatFolderLinkError in
|
||||
return .generic
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Never, JoinChatFolderLinkError> in
|
||||
account.stateManager.addUpdates(result)
|
||||
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1030,8 +1030,24 @@ public extension TelegramEngine {
|
||||
return _internal_exportChatFolder(account: self.account, filterId: filterId, title: title, peerIds: peerIds)
|
||||
}
|
||||
|
||||
public func getExportedChatLinks(id: Int32) -> Signal<[ExportedChatFolderLink], NoError> {
|
||||
return _internal_getExportedChatLinks(account: self.account, id: id)
|
||||
public func getExportedChatFolderLinks(id: Int32) -> Signal<[ExportedChatFolderLink], NoError> {
|
||||
return _internal_getExportedChatFolderLinks(account: self.account, id: id)
|
||||
}
|
||||
|
||||
public func editChatFolderLink(filterId: Int32, link: ExportedChatFolderLink, title: String?, revoke: Bool) -> Signal<Never, EditChatFolderLinkError> {
|
||||
return _internal_editChatFolderLink(account: self.account, filterId: filterId, link: link, title: title, revoke: revoke)
|
||||
}
|
||||
|
||||
public func revokeChatFolderLink(filterId: Int32, link: ExportedChatFolderLink) -> Signal<Never, RevokeChatFolderLinkError> {
|
||||
return _internal_revokeChatFolderLink(account: self.account, filterId: filterId, link: link)
|
||||
}
|
||||
|
||||
public func checkChatFolderLink(slug: String) -> Signal<ChatFolderLinkContents, CheckChatFolderLinkError> {
|
||||
return _internal_checkChatFolderLink(account: self.account, slug: slug)
|
||||
}
|
||||
|
||||
public func joinChatFolderLink(slug: String, peerIds: [EnginePeer.Id]) -> Signal<Never, JoinChatFolderLinkError> {
|
||||
return _internal_joinChatFolderLink(account: self.account, slug: slug, peerIds: peerIds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user