mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 22:25:57 +00:00
Folder updates
This commit is contained in:
@@ -60,7 +60,7 @@ func _internal_exportChatFolder(account: Account, filterId: Int32, title: String
|
||||
|> mapToSignal { inputPeers -> Signal<ExportedChatFolderLink, ExportChatFolderError> in
|
||||
return account.network.request(Api.functions.communities.exportCommunityInvite(community: .inputCommunityDialogFilter(filterId: filterId), title: title, peers: inputPeers))
|
||||
|> `catch` { error -> Signal<Api.communities.ExportedCommunityInvite, ExportChatFolderError> in
|
||||
if error.errorDescription == "INVITES_TOO_MUCH" {
|
||||
if error.errorDescription == "INVITES_TOO_MUCH" || error.errorDescription == "FILTERS_TOO_MUCH" {
|
||||
return account.postbox.transaction { transaction -> (AppConfiguration, Bool) in
|
||||
return (currentAppConfiguration(transaction: transaction), transaction.getPeer(account.peerId)?.isPremium ?? false)
|
||||
}
|
||||
@@ -69,10 +69,18 @@ func _internal_exportChatFolder(account: Account, filterId: Int32, title: String
|
||||
let userDefaultLimits = UserLimitsConfiguration(appConfiguration: appConfiguration, isPremium: false)
|
||||
let userPremiumLimits = UserLimitsConfiguration(appConfiguration: appConfiguration, isPremium: true)
|
||||
|
||||
if isPremium {
|
||||
return .fail(.limitExceeded(limit: userPremiumLimits.maxSharedFolderInviteLinks, premiumLimit: userPremiumLimits.maxSharedFolderInviteLinks))
|
||||
if error.errorDescription == "FILTERS_TOO_MUCH" {
|
||||
if isPremium {
|
||||
return .fail(.limitExceeded(limit: userPremiumLimits.maxSharedFolderJoin, premiumLimit: userPremiumLimits.maxSharedFolderJoin))
|
||||
} else {
|
||||
return .fail(.limitExceeded(limit: userDefaultLimits.maxSharedFolderJoin, premiumLimit: userPremiumLimits.maxSharedFolderJoin))
|
||||
}
|
||||
} else {
|
||||
return .fail(.limitExceeded(limit: userDefaultLimits.maxSharedFolderInviteLinks, premiumLimit: userPremiumLimits.maxSharedFolderInviteLinks))
|
||||
if isPremium {
|
||||
return .fail(.limitExceeded(limit: userPremiumLimits.maxSharedFolderInviteLinks, premiumLimit: userPremiumLimits.maxSharedFolderInviteLinks))
|
||||
} else {
|
||||
return .fail(.limitExceeded(limit: userDefaultLimits.maxSharedFolderInviteLinks, premiumLimit: userPremiumLimits.maxSharedFolderInviteLinks))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -246,7 +254,9 @@ func _internal_checkChatFolderLink(account: Account, slug: String) -> Signal<Cha
|
||||
|> mapToSignal { result -> Signal<ChatFolderLinkContents, CheckChatFolderLinkError> in
|
||||
return account.postbox.transaction { transaction -> ChatFolderLinkContents in
|
||||
switch result {
|
||||
case let .communityInvite(title, peers, chats, users):
|
||||
case let .communityInvite(_, title, emoticon, peers, chats, users):
|
||||
let _ = emoticon
|
||||
|
||||
var allPeers: [Peer] = []
|
||||
var peerPresences: [PeerId: Api.User] = [:]
|
||||
|
||||
@@ -321,7 +331,7 @@ func _internal_checkChatFolderLink(account: Account, slug: String) -> Signal<Cha
|
||||
if let peerValue = transaction.getPeer(peer.peerId) {
|
||||
resultPeers.append(EnginePeer(peerValue))
|
||||
|
||||
if transaction.getPeerChatListIndex(peer.peerId) != nil {
|
||||
if currentFilterPeers.contains(where: { $0 == peer.peerId }) && transaction.getPeerChatListIndex(peer.peerId) != nil {
|
||||
alreadyMemberPeerIds.insert(peer.peerId)
|
||||
}
|
||||
}
|
||||
@@ -407,74 +417,148 @@ func _internal_joinChatFolderLink(account: Account, slug: String, peerIds: [Engi
|
||||
public final class ChatFolderUpdates: Equatable {
|
||||
fileprivate let folderId: Int32
|
||||
fileprivate let title: String
|
||||
fileprivate let missingPeers: [Api.Peer]
|
||||
fileprivate let chats: [Api.Chat]
|
||||
fileprivate let users: [Api.User]
|
||||
fileprivate let missingPeers: [EnginePeer]
|
||||
|
||||
public var availableChatsToJoin: Int {
|
||||
return self.missingPeers.count
|
||||
}
|
||||
|
||||
public var chatFolderLinkContents: ChatFolderLinkContents {
|
||||
var peers: [EnginePeer] = []
|
||||
for missingPeer in self.missingPeers {
|
||||
for chat in chats {
|
||||
if chat.peerId == missingPeer.peerId {
|
||||
if let peer = parseTelegramGroupOrChannel(chat: chat) {
|
||||
peers.append(EnginePeer(peer))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ChatFolderLinkContents(localFilterId: self.folderId, title: self.title, peers: peers, alreadyMemberPeerIds: Set())
|
||||
return ChatFolderLinkContents(localFilterId: self.folderId, title: self.title, peers: self.missingPeers, alreadyMemberPeerIds: Set())
|
||||
}
|
||||
|
||||
fileprivate init(
|
||||
folderId: Int32,
|
||||
title: String,
|
||||
missingPeers: [Api.Peer],
|
||||
chats: [Api.Chat],
|
||||
users: [Api.User]
|
||||
missingPeers: [EnginePeer]
|
||||
) {
|
||||
self.folderId = folderId
|
||||
self.title = title
|
||||
self.missingPeers = missingPeers
|
||||
self.chats = chats
|
||||
self.users = users
|
||||
}
|
||||
|
||||
public static func ==(lhs: ChatFolderUpdates, rhs: ChatFolderUpdates) -> Bool {
|
||||
if lhs.folderId != rhs.folderId {
|
||||
return false
|
||||
}
|
||||
if lhs.missingPeers.map(\.peerId) != rhs.missingPeers.map(\.peerId) {
|
||||
if lhs.missingPeers.map(\.id) != rhs.missingPeers.map(\.id) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_getChatFolderUpdates(account: Account, folderId: Int32) -> Signal<ChatFolderUpdates?, NoError> {
|
||||
return account.network.request(Api.functions.communities.getCommunityUpdates(community: .inputCommunityDialogFilter(filterId: folderId)))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.communities.CommunityUpdates?, NoError> in
|
||||
return .single(nil)
|
||||
func _internal_pollChatFolderUpdatesOnce(account: Account, folderId: Int32) -> Signal<Never, NoError> {
|
||||
return account.postbox.transaction { transaction -> ChatListFiltersState in
|
||||
return _internal_currentChatListFiltersState(transaction: transaction)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<ChatFolderUpdates?, NoError> in
|
||||
guard let result = result else {
|
||||
|> mapToSignal { state -> Signal<Never, NoError> in
|
||||
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970)
|
||||
if let current = state.updates.first(where: { $0.folderId == folderId }) {
|
||||
let updateInterval: Int32
|
||||
#if DEBUG
|
||||
updateInterval = 5
|
||||
#else
|
||||
updateInterval = 60 * 60
|
||||
#endif
|
||||
|
||||
if current.timestamp + updateInterval >= timestamp {
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
|
||||
return account.network.request(Api.functions.communities.getCommunityUpdates(community: .inputCommunityDialogFilter(filterId: folderId)))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.communities.CommunityUpdates?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
switch result {
|
||||
case let .communityUpdates(missingPeers, chats, users):
|
||||
return account.postbox.transaction { transaction -> ChatFolderUpdates? in
|
||||
for filter in _internal_currentChatListFilters(transaction: transaction) {
|
||||
if case let .filter(id, title, _, _) = filter, id == folderId {
|
||||
return ChatFolderUpdates(folderId: folderId, title: title, missingPeers: missingPeers, chats: chats, users: users)
|
||||
}
|
||||
|> mapToSignal { result -> Signal<Never, NoError> in
|
||||
guard let result = result else {
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
let _ = updateChatListFiltersState(transaction: transaction, { state in
|
||||
var state = state
|
||||
|
||||
state.updates.removeAll(where: { $0.folderId == folderId })
|
||||
state.updates.append(ChatListFiltersState.ChatListFilterUpdates(folderId: folderId, timestamp: Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970), peerIds: []))
|
||||
|
||||
return state
|
||||
})
|
||||
}
|
||||
return nil
|
||||
|> ignoreValues
|
||||
}
|
||||
switch result {
|
||||
case let .communityUpdates(missingPeers, chats, users):
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
var peers: [Peer] = []
|
||||
var peerPresences: [PeerId: Api.User] = [:]
|
||||
|
||||
for user in users {
|
||||
let telegramUser = TelegramUser(user: user)
|
||||
peers.append(telegramUser)
|
||||
peerPresences[telegramUser.id] = user
|
||||
}
|
||||
for chat in chats {
|
||||
if let peer = parseTelegramGroupOrChannel(chat: chat) {
|
||||
peers.append(peer)
|
||||
}
|
||||
}
|
||||
|
||||
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
})
|
||||
updatePeerPresences(transaction: transaction, accountPeerId: account.peerId, peerPresences: peerPresences)
|
||||
|
||||
let _ = updateChatListFiltersState(transaction: transaction, { state in
|
||||
var state = state
|
||||
|
||||
state.updates.removeAll(where: { $0.folderId == folderId })
|
||||
state.updates.append(ChatListFiltersState.ChatListFilterUpdates(folderId: folderId, timestamp: Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970), peerIds: missingPeers.map(\.peerId)))
|
||||
|
||||
return state
|
||||
})
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func _internal_subscribedChatFolderUpdates(account: Account, folderId: Int32) -> Signal<ChatFolderUpdates?, NoError> {
|
||||
struct InternalData: Equatable {
|
||||
var title: String
|
||||
var peerIds: [EnginePeer.Id]
|
||||
}
|
||||
|
||||
return _internal_updatedChatListFiltersState(postbox: account.postbox)
|
||||
|> map { state -> InternalData? in
|
||||
guard let update = state.updates.first(where: { $0.folderId == folderId }) else {
|
||||
return nil
|
||||
}
|
||||
guard let folder = state.filters.first(where: { $0.id == folderId }) else {
|
||||
return nil
|
||||
}
|
||||
guard case let .filter(_, title, _, data) = folder, data.isShared else {
|
||||
return nil
|
||||
}
|
||||
let filteredPeerIds: [PeerId] = update.peerIds.filter { !data.includePeers.peers.contains($0) }
|
||||
return InternalData(title: title, peerIds: filteredPeerIds)
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|> mapToSignal { internalData -> Signal<ChatFolderUpdates?, NoError> in
|
||||
guard let internalData = internalData else {
|
||||
return .single(nil)
|
||||
}
|
||||
if internalData.peerIds.isEmpty {
|
||||
return .single(nil)
|
||||
}
|
||||
return account.postbox.transaction { transaction -> ChatFolderUpdates? in
|
||||
var peers: [EnginePeer] = []
|
||||
for peerId in internalData.peerIds {
|
||||
if let peer = transaction.getPeer(peerId) {
|
||||
peers.append(EnginePeer(peer))
|
||||
}
|
||||
}
|
||||
return ChatFolderUpdates(folderId: folderId, title: internalData.title, missingPeers: peers)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -530,11 +614,22 @@ func _internal_joinAvailableChatsInFolder(account: Account, updates: ChatFolderU
|
||||
}
|
||||
|
||||
func _internal_hideChatFolderUpdates(account: Account, folderId: Int32) -> Signal<Never, NoError> {
|
||||
return account.network.request(Api.functions.communities.hideCommunityUpdates(community: .inputCommunityDialogFilter(filterId: folderId)))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
return account.postbox.transaction { transaction -> Void in
|
||||
let _ = updateChatListFiltersState(transaction: transaction, { state in
|
||||
var state = state
|
||||
|
||||
state.updates.removeAll(where: { $0.folderId == folderId })
|
||||
|
||||
return state
|
||||
})
|
||||
}
|
||||
|> mapToSignal { _ -> Signal<Never, NoError> in
|
||||
return account.network.request(Api.functions.communities.hideCommunityUpdates(community: .inputCommunityDialogFilter(filterId: folderId)))
|
||||
|> `catch` { _ -> Signal<Api.Bool, NoError> in
|
||||
return .single(.boolFalse)
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
|> ignoreValues
|
||||
}
|
||||
|
||||
func _internal_leaveChatFolder(account: Account, folderId: Int32, removePeerIds: [EnginePeer.Id]) -> Signal<Never, NoError> {
|
||||
|
||||
Reference in New Issue
Block a user