Home telegram - peerInvitationImportersContext
Post
Cancel

telegram - peerInvitationImportersContext

PeerInvitationImportersContext

struct PeerInvitationImportersState

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public struct Importer: Equatable {
    public var peer: RenderedPeer
    public var date: Int32
    public var about: String?
    public var approvedBy: PeerId?
}

public var importers: [Importer]
public var isLoadingMore: Bool
public var hasLoadedOnce: Bool
public var canLoadMore: Bool
public var count: Int32

public static var Empty = PeerInvitationImportersState(importers: [], isLoadingMore: false, hasLoadedOnce: true, canLoadMore: false, count: 0)

// has doubts here for the isLoadingMore
public static var Loading = PeerInvitationImportersState(importers: [], isLoadingMore: false, hasLoadedOnce: false, canLoadMore: false, count: 0)

class PeerInvitationImportersContextImpl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
private let queue: Queue
private let account: Account
// associated peerId
private let peerId: PeerId
// associated link
private let link: String?
// requested
private let requested: Bool
// query
private let query: String?
// disposable
private let disposable = MetaDisposable()
// update disposable set
private let updateDisposables = DisposableSet()
// action disposable set
private let actionDisposables = DisposableSet()
// is loading more
private var isLoadingMore: Bool = false
// has loaded more
private var hasLoadedOnce: Bool = false
// can load more
private var canLoadMore: Bool = true
// has loaded from cache
private var loadedFromCache = false
// results
private var results: [PeerInvitationImportersState.Importer] = []
// count
private var count: Int32
// populate cache
private var populateCache: Bool = true
// is main list
private var isMainList: Bool

let state = Promise<PeerExportedInvitationsState>()

init(queue: Queue, account: Account, peerId: PeerId, adminId: PeerId?, revoked: Bool, forceUpdate: Bool) {
    self.queue = queue
    self.account = account
    self.peerId = peerId
    self.adminId = adminId ?? account.peerId
    self.revoked = revoked
    self.forceUpdate = forceUpdate
  // is main list
    self.isMainList = adminId == nil

    self.count = 0

    if adminId == nil {
        self.isLoadingMore = true
      // load from cache
        self.disposable.set((account.postbox.transaction { transaction -> CachedPeerExportedInvitations? in
            return transaction.retrieveItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerExportedInvitations, key: CachedPeerExportedInvitations.key(peerId: peerId, revoked: revoked)))?.get(CachedPeerExportedInvitations.self)
        }
        |> deliverOn(self.queue)).start(next: { [weak self] cachedResult in
            guard let strongSelf = self else {
                return
            }
            strongSelf.isLoadingMore = false
            if let cachedResult = cachedResult {
                strongSelf.results = cachedResult.invitations
                strongSelf.count = cachedResult.count
                strongSelf.hasLoadedOnce = true
                strongSelf.canLoadMore = cachedResult.canLoadMore
                strongSelf.loadedFromCache = true
            }
                                               // load more
            strongSelf.loadMore()
        }))
    }

  // load more
    self.loadMore()
}

// load more
func loadMore() {
    if self.isLoadingMore {
        return
    }
    self.isLoadingMore = true
    let account = self.account
    let peerId = self.peerId
    let adminId = self.adminId
    let revoked = self.revoked
    var lastResult = self.results.last

    if self.forceUpdate {// force update, load from start
        self.populateCache = self.isMainList
        self.forceUpdate = false
        lastResult = nil // lastResult = nil
    } else if self.loadedFromCache {
        self.populateCache = false
        self.loadedFromCache = false
    }
    let populateCache = self.populateCache

    self.disposable.set((self.account.postbox.transaction { transaction -> (peerId: Api.InputPeer?, adminId: Api.InputUser?) in
        return (transaction.getPeer(peerId).flatMap(apiInputPeer), transaction.getPeer(adminId).flatMap(apiInputUser))
    }
    |> mapToSignal { inputPeer, adminId -> Signal<([ExportedInvitation], Int32), NoError> in
        if let inputPeer = inputPeer, let adminId = adminId {
            let offsetLink = lastResult?.link
            let offsetDate = lastResult?.date
            var flags: Int32 = 0
            if let _ = offsetLink {
                flags |= (1 << 2)
            }
            if revoked {
                flags |= (1 << 3)
            }
          // Api.functions.messages.getExportedChatInvites
            let signal = account.network.request(Api.functions.messages.getExportedChatInvites(flags: flags, peer: inputPeer, adminId: adminId, offsetDate: offsetDate, offsetLink: offsetLink, limit: lastResult == nil ? 50 : 100))
            |> map(Optional.init)
            |> `catch` { _ -> Signal<Api.messages.ExportedChatInvites?, NoError> in
                return .single(nil)
            }
            |> mapToSignal { result -> Signal<([ExportedInvitation], Int32), NoError> in
                return account.postbox.transaction { transaction -> ([ExportedInvitation], Int32) in
                    guard let result = result else {
                        return ([], 0)
                    }
                    switch result {
                    case let .exportedChatInvites(count, invites, users):
                        var peers: [Peer] = []
                        for apiUser in users {
                            peers.append(TelegramUser(user: apiUser))
                        }
                        updatePeers(transaction: transaction, peers: peers, update: { _, updated in
                            return updated
                        })
                        let invitations: [ExportedInvitation] = invites.compactMap { ExportedInvitation(apiExportedInvite: $0) }
                        if populateCache {// populate cache; put cache
                            if let entry = CodableEntry(CachedPeerExportedInvitations(invitations: invitations, canLoadMore: count >= 50, count: count)) {
                                transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerExportedInvitations, key: CachedPeerExportedInvitations.key(peerId: peerId, revoked: revoked)), entry: entry, collectionSpec: cachedPeerExportedInvitationsCollectionSpec)
                            }
                        }
                        return (invitations, count)
                    }
                }
            }
            return signal
        } else {
            return .single(([], 0))
        }
    }
    |> deliverOn(self.queue)).start(next: { [weak self] invitations, updatedCount in
        guard let strongSelf = self else {
            return
        }
        if strongSelf.populateCache {
            strongSelf.populateCache = false
            strongSelf.results.removeAll()
        }
        var existingLinks = Set(strongSelf.results.map { $0.link })
        for invitation in invitations {
            if !existingLinks.contains(invitation.link) {
                strongSelf.results.append(invitation)
                existingLinks.insert(invitation.link)
            }
        }
        strongSelf.isLoadingMore = false
        strongSelf.hasLoadedOnce = true
        strongSelf.canLoadMore = !invitations.isEmpty
        if strongSelf.canLoadMore {
            strongSelf.count = max(updatedCount, Int32(strongSelf.results.count))
        } else {
            strongSelf.count = Int32(strongSelf.results.count)
        }
        strongSelf.updateState()

        if strongSelf.forceUpdate {
            strongSelf.loadMore()
        }
    }))
    self.updateState()
}

struct ExportedInvitation

1
2
3
4
5
6
7
8
9
10
11
12
public let link: String
public let title: String?
public let isPermanent: Bool
public let requestApproval: Bool
public let isRevoked: Bool
public let adminId: PeerId
public let date: Int32
public let startDate: Int32?
public let expireDate: Int32?
public let usageLimit: Int32?
public let count: Int32?
public let requestedCount: Int32?

class PeerInvitationImportersContext

1
2
3
4
5
6
7
8
9
10
11
12
public enum Subject {
    case invite(invite: ExportedInvitation, requested: Bool)
    case requests(query: String?)
}

public enum UpdateAction {
    case approve
    case deny
}

private let queue: Queue = Queue()
private let impl: QueueLocalObject<PeerInvitationImportersContextImpl>
This post is licensed under CC BY 4.0 by the author.