Skip to content

Commit

Permalink
Support loading list notifications with paging
Browse files Browse the repository at this point in the history
  • Loading branch information
manhlx3006 committed Dec 25, 2019
1 parent 59af107 commit 58e61ec
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ enum UserInfoService {
case getLatestCampaignResult(accessToken: String)
case getUserTradeCap(authToken: String, address: String)
case sendTxHash(authToken: String, txHash: String)
case getNotification(accessToken: String?)
case getNotification(accessToken: String?, pageIndex: Int)
case markAsRead(accessToken: String?, ids: [Int])
}

Expand Down Expand Up @@ -197,8 +197,8 @@ extension UserInfoService: TargetType {
return URL(string: "\(baseString)\(KNSecret.getUserTradeCapURL)?address=\(address)")!
case .sendTxHash:
return URL(string: "\(baseString)\(KNSecret.sendTxHashURL)")!
case .getNotification:
return URL(string: "\(baseString)/api/notifications")!
case .getNotification(_, let pageIndex):
return URL(string: "\(baseString)/api/notifications?page_index=\(pageIndex)&page_size=10")!
case .markAsRead:
return URL(string: "\(baseString)/api/notifications/mark_as_read")!
}
Expand Down Expand Up @@ -289,7 +289,7 @@ extension UserInfoService: TargetType {
json["Authorization"] = accessToken
case .sendTxHash(let accessToken, _):
json["Authorization"] = accessToken
case .getNotification(let accessToken):
case .getNotification(let accessToken, _):
if let token = accessToken { json["Authorization"] = token }
case .markAsRead(let accessToken, _):
if let token = accessToken { json["Authorization"] = token }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class KNListNotificationViewController: KNBaseViewController {
fileprivate let viewModel = KNListNotificationViewModel()

weak var delegate: KNListNotificationViewControllerDelegate?
fileprivate var timer: Timer?

override func viewDidLoad() {
super.viewDidLoad()
Expand All @@ -41,27 +42,21 @@ class KNListNotificationViewController: KNBaseViewController {
self.listNotiTableView.delegate = self
self.listNotiTableView.dataSource = self
self.listNotiTableView.rowHeight = 64.0

let name = Notification.Name(kUpdateListNotificationsKey)
NotificationCenter.default.addObserver(
self,
selector: #selector(self.listNotificationsDidUpdate(_:)),
name: name,
object: nil
)

self.listNotificationsDidUpdate(nil)
}

override func viewDidDisappear(_ animated: Bool) {
super.viewDidAppear(animated)
let name = Notification.Name(kUpdateListNotificationsKey)
NotificationCenter.default.removeObserver(self, name: name, object: nil)
self.timer?.invalidate()
self.timer = nil
}

override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.reloadListNotifications()
self.timer?.invalidate()
self.timer = Timer.scheduledTimer(withTimeInterval: 30.0, repeats: true, block: { [weak self] _ in
self?.reloadListNotifications()
})
}

override func viewDidLayoutSubviews() {
Expand All @@ -70,18 +65,47 @@ class KNListNotificationViewController: KNBaseViewController {
self.headerContainerView.applyGradient(with: UIColor.Kyber.headerColors)
}

fileprivate func reloadListNotifications() {
self.displayLoading()
KNNotificationCoordinator.shared.loadListNotifications { [weak self] (_, error) in
guard let `self` = self else { return }
self.hideLoading()
if let err = error {
KNCrashlyticsUtil.logCustomEvent(withName: "screen_notification", customAttributes: ["reload_error": err])
fileprivate func reloadListNotifications(_ isLoading: Bool = true) {
if isLoading { self.displayLoading() }
var errorMessage: String?
var notifications: [KNNotification] = []
let pageCount: Int = {
if KNNotificationCoordinator.shared.pageCount > 0 { return KNNotificationCoordinator.shared.pageCount }
return 1
}()
let group = DispatchGroup()
for id in 0..<pageCount {
group.enter()
KNNotificationCoordinator.shared.loadListNotifications(pageIndex: id + 1) { [weak self] (notis, error) in
guard let _ = self else {
group.leave()
return
}
if let err = error {
KNCrashlyticsUtil.logCustomEvent(withName: "screen_notification", customAttributes: ["reload_error": err])
errorMessage = err
} else {
notifications.append(contentsOf: notis)
if (id + 1) % 2 == 0 {
KNNotificationStorage.shared.updateNotificationsFromServer(notifications)
self?.listNotificationsDidUpdate(nil)
}
}
group.leave()
}
}
group.notify(queue: .main) {
if isLoading { self.hideLoading() }
if let error = errorMessage {
KNCrashlyticsUtil.logCustomEvent(withName: "screen_notification", customAttributes: ["error": error])
self.showErrorTopBannerMessage(
with: NSLocalizedString("error", comment: ""),
message: err,
message: error,
time: 1.5
)
} else {
KNNotificationStorage.shared.updateNotificationsFromServer(notifications)
self.listNotificationsDidUpdate(nil)
}
}
}
Expand Down Expand Up @@ -113,6 +137,8 @@ class KNListNotificationViewController: KNBaseViewController {
message: err,
time: 1.5
)
} else {
self.reloadListNotifications()
}
}
}
Expand All @@ -123,7 +149,13 @@ extension KNListNotificationViewController: UITableViewDelegate {
tableView.deselectRow(at: indexPath, animated: false)
let noti = self.viewModel.notifications[indexPath.row]
if !noti.read {
KNNotificationCoordinator.shared.markAsRead(ids: [noti.id]) { _ in }
KNNotificationCoordinator.shared.markAsRead(ids: [noti.id]) { _ in
let newNoti = noti.clone()
newNoti.read = true
KNNotificationStorage.shared.updateNotification(newNoti)
self.listNotificationsDidUpdate(nil)
self.reloadListNotifications(false)
}
}

KNCrashlyticsUtil.logCustomEvent(withName: "screen_notification", customAttributes: ["action": "click_\(noti.label)"])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class KNNotificationCoordinator: NSObject {

static let shared: KNNotificationCoordinator = KNNotificationCoordinator()
let provider = MoyaProvider<UserInfoService>(plugins: [MoyaCacheablePlugin()])
fileprivate(set) var numberUnread: Int = KNNotificationStorage.shared.notifications.filter({ return !$0.read }).count
fileprivate(set) var pageCount: Int = 0
fileprivate(set) var itemCount: Int = 0

fileprivate var loadingTimer: Timer?

Expand All @@ -30,28 +33,32 @@ class KNNotificationCoordinator: NSObject {

func startLoadingNotifications(_ sender: Any?) {
if KNWalletStorage.shared.wallets.isEmpty { return }
self.loadListNotifications { [weak self] (notifications, error) in
self.loadListNotifications(pageIndex: 0) { [weak self] (notifications, error) in
guard let _ = self else { return }
if error == nil {
KNNotificationStorage.shared.updateNotificationsFromServer(notifications)
}
}
}

func loadListNotifications(completion: @escaping ([KNNotification], String?) -> Void) {
func loadListNotifications(pageIndex: Int, completion: @escaping ([KNNotification], String?) -> Void) {
let accessToken = IEOUserStorage.shared.user?.accessToken
DispatchQueue.global(qos: .background).async {
self.provider.request(.getNotification(accessToken: accessToken)) { [weak self] result in
guard let _ = self else { return }
self.provider.request(.getNotification(accessToken: accessToken, pageIndex: pageIndex)) { [weak self] result in
guard let `self` = self else { return }
DispatchQueue.main.async {
switch result {
case .success(let data):
do {
let _ = try data.filterSuccessfulStatusCodes()
let json = try data.mapJSON(failsOnEmptyData: false) as? JSONDictionary ?? [:]
if let pageInfo = json["paging_info"] as? JSONDictionary {
self.numberUnread = pageInfo["unread_count"] as? Int ?? 0
self.pageCount = pageInfo["page_count"] as? Int ?? 0
self.itemCount = pageInfo["item_count"] as? Int ?? 0
}
if let jsonArr = json["data"] as? [JSONDictionary] {
let notifications = jsonArr.map({ return KNNotification(json: $0) })
KNNotificationStorage.shared.updateNotificationsFromServer(notifications)
completion(notifications, nil)
return
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ class KNNotificationStorage {
.filter({ return $0.id != -1 })
}

func updateNotification(_ noti: KNNotification) {
if self.realm == nil { return }
self.realm.add([noti], update: .modified)
try! self.realm.commitWrite()
KNNotificationUtil.postNotification(for: kUpdateListNotificationsKey)
}

func updateNotificationsFromServer(_ notifications: [KNNotification]) {
if self.realm == nil { return }
self.realm.beginWrite()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ class KNBalanceTabHamburgerMenuViewController: KNBaseViewController {
}

@objc func notificationDidUpdate(_ sender: Any?) {
let numUnread = KNNotificationStorage.shared.notifications.filter({ return !$0.read }).count
let numUnread = KNNotificationCoordinator.shared.numberUnread
self.update(notificationsCount: numUnread)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ extension KNProfileHomeCoordinator {
let message = String(format: text, name)
self.navigationController.showSuccessTopBannerMessage(with: "", message: message)
if KNAppTracker.isPriceAlertEnabled { KNPriceAlertCoordinator.shared.resume() }
KNNotificationCoordinator.shared.loadListNotifications { _, _ in }
KNNotificationCoordinator.shared.loadListNotifications(pageIndex: 0) { _, _ in }
if KNAppTracker.shouldOpenLimitOrderAfterSignedIn() {
self.navigationController.tabBarController?.selectedIndex = 2
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ extension KNProfileHomeCoordinator {
cookieJar.deleteCookie(cookie)
}

KNNotificationCoordinator.shared.loadListNotifications { _, _ in }
KNNotificationCoordinator.shared.loadListNotifications(pageIndex: 0) { _, _ in }
}

// Get current user's info data, to sync between mobile (iOS + Android) and web
Expand Down

0 comments on commit 58e61ec

Please sign in to comment.