Merge branch 'mkirk/pull-to-refresh-inbox' into release/2.18.0

pull/1/head
Michael Kirk 8 years ago
commit 69ee9cbcfa

@ -833,10 +833,11 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
// Fetch messages as soon as possible after launching. In particular, when // Fetch messages as soon as possible after launching. In particular, when
// launching from the background, without this, we end up waiting some extra // launching from the background, without this, we end up waiting some extra
// seconds before receiving an actionable push notification. // seconds before receiving an actionable push notification.
[[Environment getCurrent].messageFetcherJob runAsync]; __unused AnyPromise *messagePromise = [[Environment getCurrent].messageFetcherJob run];
// This should happen at any launch, background or foreground. // This should happen at any launch, background or foreground.
__unused AnyPromise *promise = [OWSSyncPushTokensJob runWithAccountManager:[Environment getCurrent].accountManager __unused AnyPromise *pushTokenpromise =
[OWSSyncPushTokensJob runWithAccountManager:[Environment getCurrent].accountManager
preferences:[Environment preferences]]; preferences:[Environment preferences]];
} }

@ -8,15 +8,14 @@ import PromiseKit
@objc(OWSMessageFetcherJob) @objc(OWSMessageFetcherJob)
class MessageFetcherJob: NSObject { class MessageFetcherJob: NSObject {
let TAG = "[MessageFetcherJob]" private let TAG = "[MessageFetcherJob]"
var timer: Timer?
// MARK: injected dependencies private var timer: Timer?
let networkManager: TSNetworkManager
let messageReceiver: OWSMessageReceiver
let signalService: OWSSignalService
var runPromises = [Double: Promise<Void>]() // MARK: injected dependencies
private let networkManager: TSNetworkManager
private let messageReceiver: OWSMessageReceiver
private let signalService: OWSSignalService
init(messageReceiver: OWSMessageReceiver, networkManager: TSNetworkManager, signalService: OWSSignalService) { init(messageReceiver: OWSMessageReceiver, networkManager: TSNetworkManager, signalService: OWSSignalService) {
self.messageReceiver = messageReceiver self.messageReceiver = messageReceiver
@ -24,53 +23,58 @@ class MessageFetcherJob: NSObject {
self.signalService = signalService self.signalService = signalService
} }
func runAsync() { public func run() -> Promise<Void> {
Logger.debug("\(TAG) \(#function)") Logger.debug("\(TAG) in \(#function)")
guard signalService.isCensorshipCircumventionActive else { guard signalService.isCensorshipCircumventionActive else {
Logger.debug("\(self.TAG) delegating message fetching to SocketManager since we're using normal transport.") Logger.debug("\(self.TAG) delegating message fetching to SocketManager since we're using normal transport.")
TSSocketManager.requestSocketOpen() TSSocketManager.requestSocketOpen()
return return Promise(value: ())
} }
Logger.info("\(TAG) using fallback message fetching.") Logger.info("\(TAG) fetching messages via REST.")
let promiseId = NSDate().timeIntervalSince1970 let promise = self.fetchUndeliveredMessages().then { (envelopes: [OWSSignalServiceProtosEnvelope], more: Bool) -> Promise<Void> in
Logger.debug("\(self.TAG) starting promise: \(promiseId)")
let runPromise = self.fetchUndeliveredMessages().then { (envelopes: [OWSSignalServiceProtosEnvelope], more: Bool) -> Void in
for envelope in envelopes { for envelope in envelopes {
Logger.info("\(self.TAG) received envelope.") Logger.info("\(self.TAG) received envelope.")
self.messageReceiver.handleReceivedEnvelope(envelope) self.messageReceiver.handleReceivedEnvelope(envelope)
self.acknowledgeDelivery(envelope: envelope) self.acknowledgeDelivery(envelope: envelope)
} }
if more { if more {
Logger.info("\(self.TAG) more messages, so recursing.") Logger.info("\(self.TAG) fetching more messages.")
// recurse return self.run()
self.runAsync() } else {
// All finished
return Promise(value: ())
} }
}.always {
Logger.debug("\(self.TAG) cleaning up promise: \(promiseId)")
self.runPromises[promiseId] = nil
} }
// maintain reference to make sure it's not de-alloced prematurely. promise.retainUntilComplete()
runPromises[promiseId] = runPromise
return promise
}
@objc func run() -> AnyPromise {
return AnyPromise(run())
} }
// use in DEBUG or wherever you can't receive push notifications to poll for messages. // use in DEBUG or wherever you can't receive push notifications to poll for messages.
// Do not use in production. // Do not use in production.
func startRunLoop(timeInterval: Double) { public func startRunLoop(timeInterval: Double) {
Logger.error("\(TAG) Starting message fetch polling. This should not be used in production.") Logger.error("\(TAG) Starting message fetch polling. This should not be used in production.")
timer = WeakTimer.scheduledTimer(timeInterval: timeInterval, target: self, userInfo: nil, repeats: true) {[weak self] _ in timer = WeakTimer.scheduledTimer(timeInterval: timeInterval, target: self, userInfo: nil, repeats: true) {[weak self] _ in
self?.runAsync() let _: Promise<Void>? = self?.run()
return
} }
} }
func stopRunLoop() { public func stopRunLoop() {
timer?.invalidate() timer?.invalidate()
timer = nil timer = nil
} }
func parseMessagesResponse(responseObject: Any?) -> (envelopes: [OWSSignalServiceProtosEnvelope], more: Bool)? { private func parseMessagesResponse(responseObject: Any?) -> (envelopes: [OWSSignalServiceProtosEnvelope], more: Bool)? {
guard let responseObject = responseObject else { guard let responseObject = responseObject else {
Logger.error("\(self.TAG) response object was surpringly nil") Logger.error("\(self.TAG) response object was surpringly nil")
return nil return nil
@ -103,7 +107,7 @@ class MessageFetcherJob: NSObject {
) )
} }
func buildEnvelope(messageDict: [String: Any]) -> OWSSignalServiceProtosEnvelope? { private func buildEnvelope(messageDict: [String: Any]) -> OWSSignalServiceProtosEnvelope? {
let builder = OWSSignalServiceProtosEnvelopeBuilder() let builder = OWSSignalServiceProtosEnvelopeBuilder()
guard let typeInt = messageDict["type"] as? Int32 else { guard let typeInt = messageDict["type"] as? Int32 else {
@ -156,7 +160,7 @@ class MessageFetcherJob: NSObject {
return builder.build() return builder.build()
} }
func fetchUndeliveredMessages() -> Promise<(envelopes: [OWSSignalServiceProtosEnvelope], more: Bool)> { private func fetchUndeliveredMessages() -> Promise<(envelopes: [OWSSignalServiceProtosEnvelope], more: Bool)> {
return Promise { fulfill, reject in return Promise { fulfill, reject in
let messagesRequest = OWSGetMessagesRequest() let messagesRequest = OWSGetMessagesRequest()
@ -181,7 +185,7 @@ class MessageFetcherJob: NSObject {
} }
} }
func acknowledgeDelivery(envelope: OWSSignalServiceProtosEnvelope) { private func acknowledgeDelivery(envelope: OWSSignalServiceProtosEnvelope) {
let request = OWSAcknowledgeMessageDeliveryRequest(source: envelope.source, timestamp: envelope.timestamp) let request = OWSAcknowledgeMessageDeliveryRequest(source: envelope.source, timestamp: envelope.timestamp)
self.networkManager.makeRequest(request, self.networkManager.makeRequest(request,
success: { (_: URLSessionDataTask?, _: Any?) -> Void in success: { (_: URLSessionDataTask?, _: Any?) -> Void in

@ -216,6 +216,13 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
[emptyBoxLabel autoPinToTopLayoutGuideOfViewController:self withInset:0]; [emptyBoxLabel autoPinToTopLayoutGuideOfViewController:self withInset:0];
[emptyBoxLabel autoPinToBottomLayoutGuideOfViewController:self withInset:0]; [emptyBoxLabel autoPinToBottomLayoutGuideOfViewController:self withInset:0];
UIRefreshControl *pullToRefreshView = [UIRefreshControl new];
pullToRefreshView.tintColor = [UIColor grayColor];
[pullToRefreshView addTarget:self
action:@selector(pullToRefreshPerformed:)
forControlEvents:UIControlEventValueChanged];
[self.tableView insertSubview:pullToRefreshView atIndex:0];
[self updateReminderViews]; [self updateReminderViews];
} }
@ -596,6 +603,16 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
return InboxTableViewCell.rowHeight; return InboxTableViewCell.rowHeight;
} }
- (void)pullToRefreshPerformed:(UIRefreshControl *)refreshControl
{
OWSAssert([NSThread isMainThread]);
DDLogInfo(@"%@ beggining refreshing.", self.tag);
[[Environment getCurrent].messageFetcherJob run].always(^{
DDLogInfo(@"%@ ending refreshing.", self.tag);
[refreshControl endRefreshing];
});
}
#pragma mark Table Swipe to Delete #pragma mark Table Swipe to Delete
- (void)tableView:(UITableView *)tableView - (void)tableView:(UITableView *)tableView
@ -605,7 +622,6 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
return; return;
} }
- (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath - (NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
{ {
UITableViewRowAction *deleteAction = UITableViewRowAction *deleteAction =

@ -101,11 +101,11 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe
{ {
DDLogInfo(@"%@ received remote notification", self.tag); DDLogInfo(@"%@ received remote notification", self.tag);
[self.messageFetcherJob runAsync]; [self.messageFetcherJob run];
} }
- (void)applicationDidBecomeActive { - (void)applicationDidBecomeActive {
[self.messageFetcherJob runAsync]; [self.messageFetcherJob run];
} }
/** /**

Loading…
Cancel
Save