Skip to content

Commit 5943660

Browse files
0.6.0 (#22)
Enhanced Pagination for User Retrieval and Dialog Synchronization Implemented pagination across user selection, member management, and dialog synchronization to improve performance and scrolling experience. Key Changes: - User Selection: Added pagination to CreateDialogViewModel, ensuring efficient user retrieval and seamless infinite scrolling. - Member Management: Introduced paginated user fetching in RemoveMembersView and MembersDialogViewModel to reduce redundant API calls. - Data Synchronization: Improved SyncDialog to handle paginated user synchronization, ensuring batch processing and efficient retrieval. - Performance Optimizations: Centralized pagination settings, refined API integration, and enhanced async handling to avoid redundant requests and ensure smooth UI updates.
1 parent ac833e8 commit 5943660

26 files changed

+461
-190
lines changed

Sources/QuickBloxData/Pagination/Pagination.swift

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@
99
import Foundation
1010
import QuickBloxDomain
1111

12+
public class PaginationSettings {
13+
public var limit: Int = 100
14+
}
15+
1216
public struct Pagination: PaginationProtocol {
17+
18+
public static var limit: Int {
19+
return QuickBloxData.settings.pagination.limit
20+
}
21+
1322
public var skip: Int
1423
public let limit: Int
1524
public let total: Int
@@ -22,15 +31,15 @@ public struct Pagination: PaginationProtocol {
2231
return (total + limit - 1) / limit
2332
}
2433

25-
public var hasNextPage: Bool = false
34+
public var hasNext: Bool = false
2635

27-
public init(skip: Int, limit: Int, total: Int) {
36+
public init(skip: Int, limit: Int = Pagination.limit, total: Int = 0) {
2837
self.skip = skip
2938
self.limit = limit
3039
self.total = total
3140
}
3241

33-
public init(page: Int = 1, perPage: Int = 10, total: Int = 0) {
42+
public init(page: Int = 1, perPage: Int = Pagination.limit, total: Int = 0) {
3443
self.skip = (page - 1) * perPage
3544
self.limit = perPage
3645
self.total = total
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//
2+
// QuickBloxData.swift
3+
// QuickBloxUIKit
4+
//
5+
// Created by Injoit on 24.02.2025.
6+
// Copyright © 2025 QuickBlox. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
public class DataSettings {
12+
public let pagination = PaginationSettings()
13+
}
14+
15+
public var settings: DataSettings = .init()

Sources/QuickBloxData/Repository/DialogsRepository.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ public class DialogsRepository {
2424
}
2525

2626
extension DialogsRepository: DialogsRepositoryProtocol {
27+
public var initialPagination: Pagination {
28+
Pagination()
29+
}
30+
2731
public var remoteEventPublisher: AnyPublisher<RemoteDialogEvent<Message>, Never> {
2832
get async {
2933
await remote.eventPublisher

Sources/QuickBloxData/Repository/MessagesRepository.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ extension Message {
168168
}
169169

170170
extension MessagesRepository {
171+
public var initialPagination: Pagination {
172+
Pagination()
173+
}
174+
171175
public func send(messageToRemote entity: Message) async throws {
172176
do {
173177
_ = try await remote.send(message: RemoteMessageDTO(entity))

Sources/QuickBloxData/Repository/UsersRepository.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ extension LocalUserDTO {
6363
}
6464

6565
extension UsersRepository: UsersRepositoryProtocol {
66+
public var initialPagination: Pagination {
67+
Pagination()
68+
}
69+
6670
public func save(userToLocal entity: User) async throws {
6771
do {
6872
try await local.save(user: LocalUserDTO(entity))
@@ -99,27 +103,24 @@ extension UsersRepository: UsersRepositoryProtocol {
99103
}
100104
}
101105

102-
public func get(usersFromRemote usersIds: [String]) async throws -> [User] {
103-
var pagination = Pagination(skip: 0, limit: usersIds.count)
104-
if usersIds.isEmpty {
105-
pagination = Pagination(skip: 0, limit: 30)
106-
}
106+
public func get(usersFromRemote usersIds: [String], pagination: Pagination? = nil) async throws -> (users: [User], pagination: Pagination) {
107+
let pagination = pagination ?? Pagination(skip: 0)
107108
do {
108109
let withIds = RemoteUsersDTO(ids: usersIds,
109110
pagination: pagination)
110111
let data = try await remote.get(users: withIds)
111-
return data.users.map { User($0) }
112+
return (users: data.users.map { User($0) }, pagination: data.pagination)
112113
} catch {
113114
throw try error.repositoryException
114115
}
115116
}
116117

117-
public func get(usersFromRemote fullName: String) async throws -> [User] {
118+
public func get(usersFromRemote fullName: String, pagination: Pagination? = nil) async throws -> (users: [User], pagination: Pagination) {
118119
do {
119-
let pagination = Pagination(skip: 0, limit: 100)
120+
let pagination = pagination ?? Pagination(skip: 0)
120121
let withFullName = RemoteUsersDTO(name:fullName, pagination: pagination)
121122
let data = try await remote.get(users: withFullName)
122-
return data.users.map { User($0) }
123+
return (users: data.users.map { User($0) }, pagination: data.pagination)
123124
} catch {
124125
throw try error.repositoryException
125126
}

Sources/QuickBloxData/Source/Local/PermissionsDataSourceProtocol.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
// PermissionsDataSourceProtocol.swift
33
// QuickBloxUIKit
44
//
5-
// Created by Injoit on Illia Chemolosov on 28.01.2025.
6-
// Copyright © 2023 QuickBlox. All rights reserved.
5+
// Created by Injoit on 28.01.2025.
6+
// Copyright © 2025 QuickBlox. All rights reserved.
77
//
88

99
import QuickBloxDomain

Sources/QuickBloxData/Source/Remote/API/API.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extension Pagination {
2121
self.init(page: Int(page.currentPage),
2222
perPage: Int(page.perPage),
2323
total: Int(page.totalEntries))
24+
self.hasNext = self.total > self.skip + self.limit
2425
}
2526
}
2627

@@ -29,13 +30,15 @@ extension Pagination {
2930
self.init(skip: page.skip,
3031
limit: page.limit,
3132
total: Int(page.totalEntries))
33+
self.hasNext = self.total > self.skip + self.limit
3234
}
3335
}
3436

3537
extension QBGeneralResponsePage {
3638
convenience init(_ pagination: Pagination) {
3739
self.init(currentPage: UInt(pagination.currentPage + 1),
38-
perPage: UInt(pagination.limit))
40+
perPage: UInt(pagination.limit),
41+
totalEntries: 0)
3942
}
4043
}
4144

Sources/QuickBloxData/Source/Remote/API/APIUsers.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public struct APIUsers {
4343

4444
return try await withCheckedThrowingContinuation { continuation in
4545
let page = QBGeneralResponsePage(page)
46+
4647
QBRequest.users(withExtendedRequest: extendedRequest, page: page) {
4748
_, page, users in
4849
continuation.resume(returning: (users, Pagination(page)))

Sources/QuickBloxData/Source/Remote/Chat.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private actor Chat {
119119
private extension QBChatDialog {
120120
func joinAsync() async throws {
121121
return try await withCheckedThrowingContinuation { continuation in
122-
if type == .private || isJoined() == true {
122+
if type == .private || type == .publicGroup || isJoined() == true {
123123
continuation.resume()
124124
} else {
125125
join { error in

Sources/QuickBloxData/Source/Remote/RemoteDataSource.swift

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,7 @@ open class RemoteDataSource: NSObject, RemoteDataSourceProtocol, QBChatDelegate
394394
}
395395
let dialogs = result.dialogs.map { RemoteDialogDTO($0) }
396396
let usersIds = result.usersIds.map { $0.stringValue }
397-
let pagination = Pagination(skip: result.page.skip,
398-
limit: result.page.limit,
399-
total: Int(result.page.totalEntries))
397+
let pagination = Pagination(result.page)
400398
let dialogsDTO = RemoteDialogsDTO(dialogs: dialogs,
401399
usersIds: usersIds,
402400
pagination: pagination)
@@ -551,8 +549,18 @@ open class RemoteDataSource: NSObject, RemoteDataSourceProtocol, QBChatDelegate
551549
do {
552550
var tuple: (users: [QBUUser], pagination: Pagination)
553551
if dto.ids.isEmpty == false {
554-
tuple = try await api.users.get(with: dto.ids,
555-
page: dto.pagination)
552+
let limit = 100
553+
let requestPage = Pagination(skip: 0, limit: limit)
554+
let offset = dto.pagination.skip
555+
let count = dto.ids.count
556+
let requestIds = Array(dto.ids[offset..<min(offset + limit, count)])
557+
tuple = try await api.users.get(with: requestIds,
558+
page: requestPage)
559+
var responsePage = Pagination(skip: dto.pagination.skip,
560+
limit: limit,
561+
total: dto.ids.count)
562+
responsePage.hasNext = responsePage.total > (responsePage.skip + responsePage.limit)
563+
tuple.pagination = responsePage
556564
} else if dto.name.isEmpty == false {
557565
tuple = try await api.users.get(with: dto.name,
558566
page: dto.pagination)

0 commit comments

Comments
 (0)