mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-31 18:02:20 +00:00
+ Added preliminary load mechanics for Feedback Images.
This commit is contained in:
parent
5038c3e4e9
commit
3aa45bbb9f
@ -81,7 +81,7 @@
|
||||
_requireUserEmail = BITFeedbackUserDataElementOptional;
|
||||
_showAlertOnIncomingMessages = YES;
|
||||
_showFirstRequiredPresentationModal = YES;
|
||||
|
||||
|
||||
_disableFeedbackManager = NO;
|
||||
_networkRequestInProgress = NO;
|
||||
_incomingMessagesAlertShowing = NO;
|
||||
@ -90,9 +90,9 @@
|
||||
_lastMessageID = nil;
|
||||
|
||||
self.feedbackList = [NSMutableArray array];
|
||||
|
||||
|
||||
_fileManager = [[NSFileManager alloc] init];
|
||||
|
||||
|
||||
_settingsFile = [bit_settingsDir() stringByAppendingPathComponent:BITHOCKEY_FEEDBACK_SETTINGS];
|
||||
|
||||
_userID = nil;
|
||||
@ -152,12 +152,12 @@
|
||||
}
|
||||
if(nil == _networkDidBecomeReachableObserver) {
|
||||
_networkDidBecomeReachableObserver = [[NSNotificationCenter defaultCenter] addObserverForName:BITHockeyNetworkDidBecomeReachableNotification
|
||||
object:nil
|
||||
queue:NSOperationQueue.mainQueue
|
||||
usingBlock:^(NSNotification *note) {
|
||||
typeof(self) strongSelf = weakSelf;
|
||||
[strongSelf didBecomeActiveActions];
|
||||
}];
|
||||
object:nil
|
||||
queue:NSOperationQueue.mainQueue
|
||||
usingBlock:^(NSNotification *note) {
|
||||
typeof(self) strongSelf = weakSelf;
|
||||
[strongSelf didBecomeActiveActions];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,9 +228,9 @@
|
||||
}
|
||||
BITFeedbackComposeViewController *composeView = [self feedbackComposeViewController];
|
||||
[composeView prepareWithItems:items];
|
||||
|
||||
|
||||
[self showView:composeView];
|
||||
|
||||
|
||||
}
|
||||
|
||||
- (void)showFeedbackComposeViewWithGeneratedScreenshot {
|
||||
@ -242,7 +242,7 @@
|
||||
|
||||
- (void)startManager {
|
||||
if ([self isFeedbackManagerDisabled]) return;
|
||||
|
||||
|
||||
[self registerObservers];
|
||||
|
||||
// we are already delayed, so the notification already came in and this won't invoked twice
|
||||
@ -289,12 +289,12 @@
|
||||
userIDForHockeyManager:[BITHockeyManager sharedHockeyManager]
|
||||
componentManager:self];
|
||||
}
|
||||
|
||||
|
||||
if (userID) {
|
||||
availableViaDelegate = YES;
|
||||
self.userID = userID;
|
||||
}
|
||||
|
||||
|
||||
return availableViaDelegate;
|
||||
}
|
||||
|
||||
@ -306,16 +306,16 @@
|
||||
if ([BITHockeyManager sharedHockeyManager].delegate &&
|
||||
[[BITHockeyManager sharedHockeyManager].delegate respondsToSelector:@selector(userNameForHockeyManager:componentManager:)]) {
|
||||
userName = [[BITHockeyManager sharedHockeyManager].delegate
|
||||
userNameForHockeyManager:[BITHockeyManager sharedHockeyManager]
|
||||
componentManager:self];
|
||||
userNameForHockeyManager:[BITHockeyManager sharedHockeyManager]
|
||||
componentManager:self];
|
||||
}
|
||||
|
||||
|
||||
if (userName) {
|
||||
availableViaDelegate = YES;
|
||||
self.userName = userName;
|
||||
self.requireUserName = BITFeedbackUserDataElementDontShow;
|
||||
}
|
||||
|
||||
|
||||
return availableViaDelegate;
|
||||
}
|
||||
|
||||
@ -323,20 +323,20 @@
|
||||
BOOL availableViaDelegate = NO;
|
||||
|
||||
NSString *userEmail = [self stringValueFromKeychainForKey:kBITHockeyMetaUserEmail];
|
||||
|
||||
|
||||
if ([BITHockeyManager sharedHockeyManager].delegate &&
|
||||
[[BITHockeyManager sharedHockeyManager].delegate respondsToSelector:@selector(userEmailForHockeyManager:componentManager:)]) {
|
||||
userEmail = [[BITHockeyManager sharedHockeyManager].delegate
|
||||
userEmailForHockeyManager:[BITHockeyManager sharedHockeyManager]
|
||||
componentManager:self];
|
||||
}
|
||||
|
||||
|
||||
if (userEmail) {
|
||||
availableViaDelegate = YES;
|
||||
self.userEmail = userEmail;
|
||||
self.requireUserEmail = BITFeedbackUserDataElementDontShow;
|
||||
}
|
||||
|
||||
|
||||
return availableViaDelegate;
|
||||
}
|
||||
|
||||
@ -344,7 +344,7 @@
|
||||
[self updateUserIDUsingKeychainAndDelegate];
|
||||
[self updateUserNameUsingKeychainAndDelegate];
|
||||
[self updateUserEmailUsingKeychainAndDelegate];
|
||||
|
||||
|
||||
// if both values are shown via the delegates, we never ever did ask and will never ever ask for user data
|
||||
if (self.requireUserName == BITFeedbackUserDataElementDontShow &&
|
||||
self.requireUserEmail == BITFeedbackUserDataElementDontShow) {
|
||||
@ -361,7 +361,7 @@
|
||||
|
||||
if (![_fileManager fileExistsAtPath:_settingsFile])
|
||||
return;
|
||||
|
||||
|
||||
NSData *codedData = [[NSData alloc] initWithContentsOfFile:_settingsFile];
|
||||
if (codedData == nil) return;
|
||||
|
||||
@ -373,7 +373,7 @@
|
||||
@catch (NSException *exception) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!userIDViaDelegate) {
|
||||
if ([unarchiver containsValueForKey:kBITFeedbackUserID]) {
|
||||
self.userID = [unarchiver decodeObjectForKey:kBITFeedbackUserID];
|
||||
@ -389,7 +389,7 @@
|
||||
}
|
||||
self.userName = [self stringValueFromKeychainForKey:kBITFeedbackName];
|
||||
}
|
||||
|
||||
|
||||
if (!userEmailViaDelegate) {
|
||||
if ([unarchiver containsValueForKey:kBITFeedbackEmail]) {
|
||||
self.userEmail = [unarchiver decodeObjectForKey:kBITFeedbackEmail];
|
||||
@ -409,7 +409,7 @@
|
||||
|
||||
if ([unarchiver containsValueForKey:kBITFeedbackAppID]) {
|
||||
NSString *appID = [unarchiver decodeObjectForKey:kBITFeedbackAppID];
|
||||
|
||||
|
||||
// the stored thread is from another application identifier, so clear the token
|
||||
// which will cause the new posts to create a new thread on the server for the
|
||||
// current app identifier
|
||||
@ -432,9 +432,9 @@
|
||||
// inform the UI to update its data in case the list is already showing
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:BITHockeyFeedbackMessagesLoadingFinished object:nil];
|
||||
}
|
||||
|
||||
|
||||
[unarchiver finishDecoding];
|
||||
|
||||
|
||||
if (!self.lastCheck) {
|
||||
self.lastCheck = [NSDate distantPast];
|
||||
}
|
||||
@ -446,7 +446,7 @@
|
||||
|
||||
NSMutableData *data = [[NSMutableData alloc] init];
|
||||
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
|
||||
|
||||
|
||||
if (_didAskUserData)
|
||||
[archiver encodeObject:[NSNumber numberWithBool:YES] forKey:kBITFeedbackUserDataAsked];
|
||||
|
||||
@ -631,7 +631,7 @@
|
||||
|
||||
- (BOOL)isManualUserDataAvailable {
|
||||
[self updateAppDefinedUserData];
|
||||
|
||||
|
||||
if ((self.requireUserName != BITFeedbackUserDataElementDontShow && self.userName) ||
|
||||
(self.requireUserEmail != BITFeedbackUserDataElementDontShow && self.userEmail))
|
||||
return YES;
|
||||
@ -645,23 +645,23 @@
|
||||
- (void)updateMessageListFromResponse:(NSDictionary *)jsonDictionary {
|
||||
if (!jsonDictionary) {
|
||||
// nil is used when the server returns 404, so we need to mark all existing threads as archives and delete the discussion token
|
||||
|
||||
|
||||
NSArray *messagesSendInProgress = [self messagesWithStatus:BITFeedbackMessageStatusSendInProgress];
|
||||
NSInteger pendingMessagesCount = [messagesSendInProgress count] + [[self messagesWithStatus:BITFeedbackMessageStatusSendPending] count];
|
||||
|
||||
|
||||
[self markSendInProgressMessagesAsPending];
|
||||
|
||||
[_feedbackList enumerateObjectsUsingBlock:^(id objMessage, NSUInteger messagesIdx, BOOL *stop) {
|
||||
if ([(BITFeedbackMessage *)objMessage status] != BITFeedbackMessageStatusSendPending)
|
||||
[(BITFeedbackMessage *)objMessage setStatus:BITFeedbackMessageStatusArchived];
|
||||
}];
|
||||
|
||||
|
||||
if ([self token]) {
|
||||
self.token = nil;
|
||||
}
|
||||
|
||||
NSInteger pendingMessagesCountAfterProcessing = [[self messagesWithStatus:BITFeedbackMessageStatusSendPending] count];
|
||||
|
||||
|
||||
[self saveMessages];
|
||||
|
||||
// check if this request was successful and we have more messages pending and continue if positive
|
||||
@ -710,7 +710,7 @@
|
||||
*stop2 = YES;
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
if (matchingSendInProgressOrInConflictMessage) {
|
||||
matchingSendInProgressOrInConflictMessage.date = [self parseRFC3339Date:[(NSDictionary *)objMessage objectForKey:@"created_at"]];
|
||||
matchingSendInProgressOrInConflictMessage.id = messageID;
|
||||
@ -734,6 +734,15 @@
|
||||
message.id = [(NSDictionary *)objMessage objectForKey:@"id"];
|
||||
message.status = BITFeedbackMessageStatusUnread;
|
||||
|
||||
for (NSDictionary *attachmentData in objMessage[@"attachments"]){
|
||||
BITFeedbackMessageAttachment *newAttachment = [BITFeedbackMessageAttachment new];
|
||||
newAttachment.originalFilename = attachmentData[@"file_name"];
|
||||
newAttachment.id = attachmentData[@"id"];
|
||||
newAttachment.sourceURL = attachmentData[@"url"];
|
||||
newAttachment.contentType = @"image/jpg";
|
||||
[message addAttachmentsObject:newAttachment];
|
||||
}
|
||||
|
||||
[_feedbackList addObject:message];
|
||||
|
||||
newMessage = YES;
|
||||
@ -750,7 +759,7 @@
|
||||
|
||||
[self sortFeedbackList];
|
||||
[self updateLastMessageID];
|
||||
|
||||
|
||||
// we got a new incoming message, trigger user notification system
|
||||
if (newMessage) {
|
||||
// check if the latest message is from the users own email address, then don't show an alert since he answered using his own email
|
||||
@ -759,12 +768,12 @@
|
||||
BITFeedbackMessage *latestMessage = [self lastMessageHavingID];
|
||||
if (self.userEmail && latestMessage.email && [self.userEmail compare:latestMessage.email] == NSOrderedSame)
|
||||
latestMessageFromUser = YES;
|
||||
|
||||
|
||||
if (!latestMessageFromUser) {
|
||||
if([self.delegate respondsToSelector:@selector(feedbackManagerDidReceiveNewFeedback:)]) {
|
||||
[self.delegate feedbackManagerDidReceiveNewFeedback:self];
|
||||
}
|
||||
|
||||
|
||||
if(self.showAlertOnIncomingMessages && !self.currentFeedbackListViewController && !self.currentFeedbackComposeViewController) {
|
||||
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:BITHockeyLocalizedString(@"HockeyFeedbackNewMessageTitle")
|
||||
message:BITHockeyLocalizedString(@"HockeyFeedbackNewMessageText")
|
||||
@ -780,7 +789,7 @@
|
||||
}
|
||||
|
||||
NSInteger pendingMessagesCountAfterProcessing = [[self messagesWithStatus:BITFeedbackMessageStatusSendPending] count];
|
||||
|
||||
|
||||
// check if this request was successful and we have more messages pending and continue if positive
|
||||
if (pendingMessagesCount > pendingMessagesCountAfterProcessing && pendingMessagesCountAfterProcessing > 0) {
|
||||
[self performSelector:@selector(submitPendingMessages) withObject:nil afterDelay:0.1];
|
||||
@ -790,18 +799,52 @@
|
||||
[self markSendInProgressMessagesAsPending];
|
||||
}
|
||||
|
||||
[self synchronizeMissingAttachments];
|
||||
|
||||
[self saveMessages];
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
Load all attachments without any local data to have them available.
|
||||
*/
|
||||
-(BOOL)synchronizeMissingAttachments {
|
||||
// Extract all Attachments.
|
||||
NSMutableArray *allAttachments = [NSMutableArray new];
|
||||
for (int i = 0; i < [self numberOfMessages]; i++){
|
||||
BITFeedbackMessage *message = [self messageAtIndex:i];
|
||||
for (BITFeedbackMessageAttachment *attachment in message.attachments){
|
||||
if (attachment.needsLoadingFromURL){
|
||||
[allAttachments addObject:attachment];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (BITFeedbackMessageAttachment *attachment in allAttachments){
|
||||
// we will just update the objects here and perform a save after each successful load operation.
|
||||
|
||||
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:attachment.sourceURL]];
|
||||
__weak BITFeedbackManager *weakSelf = self;
|
||||
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *err) {
|
||||
if (responseData.length){
|
||||
[attachment replaceData:responseData];
|
||||
[weakSelf saveMessages];
|
||||
|
||||
}
|
||||
}];
|
||||
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)sendNetworkRequestWithHTTPMethod:(NSString *)httpMethod withMessage:(BITFeedbackMessage *)message completionHandler:(void (^)(NSError *err))completionHandler {
|
||||
NSString *boundary = @"----FOO";
|
||||
|
||||
_networkRequestInProgress = YES;
|
||||
// inform the UI to update its data in case the list is already showing
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:BITHockeyFeedbackMessagesLoadingStarted object:nil];
|
||||
|
||||
|
||||
NSString *tokenParameter = @"";
|
||||
if ([self token]) {
|
||||
tokenParameter = [NSString stringWithFormat:@"/%@", [self token]];
|
||||
@ -879,7 +922,7 @@
|
||||
}
|
||||
|
||||
[postBody appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
|
||||
|
||||
[request setHTTPBody:postBody];
|
||||
}
|
||||
@ -902,14 +945,14 @@
|
||||
if (!self.token) {
|
||||
// set the token to the first message token, since this is identical
|
||||
__block NSString *token = nil;
|
||||
|
||||
|
||||
[_feedbackList enumerateObjectsUsingBlock:^(id objMessage, NSUInteger messagesIdx, BOOL *stop) {
|
||||
if ([(BITFeedbackMessage *)objMessage status] == BITFeedbackMessageStatusSendInProgress) {
|
||||
token = [(BITFeedbackMessage *)objMessage token];
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
|
||||
|
||||
if (token) {
|
||||
self.token = token;
|
||||
}
|
||||
@ -982,7 +1025,7 @@
|
||||
[self saveMessages];
|
||||
|
||||
NSArray *pendingMessages = [self messagesWithStatus:BITFeedbackMessageStatusSendPending];
|
||||
|
||||
|
||||
if ([pendingMessages count] > 0) {
|
||||
// we send one message at a time
|
||||
BITFeedbackMessage *messageToSend = [pendingMessages objectAtIndex:0];
|
||||
@ -1041,11 +1084,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Observation Handling
|
||||
#pragma mark - Observation Handling
|
||||
|
||||
-(void)setFeedbackObservationMode:(BITFeedbackObservationMode)mode {
|
||||
if (mode == BITFeedbackObservationModeOnScreenshot){
|
||||
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(screenshotNotificationReceived:) name:UIApplicationUserDidTakeScreenshotNotification object:nil];
|
||||
// [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(screenshotNotificationReceived:) name:UIApplicationUserDidTakeScreenshotNotification object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class BITFeedbackMessageAttachment;
|
||||
|
||||
/**
|
||||
* Status for each feedback message
|
||||
*/
|
||||
@ -79,5 +81,7 @@ typedef NS_ENUM(NSInteger, BITFeedbackMessageStatus) {
|
||||
*/
|
||||
-(void)deleteContents;
|
||||
|
||||
-(void)addAttachmentsObject:(BITFeedbackMessageAttachment *)object;
|
||||
|
||||
|
||||
@end
|
||||
|
@ -90,5 +90,10 @@
|
||||
[attachment deleteContents];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)addAttachmentsObject:(BITFeedbackMessageAttachment *)object{
|
||||
if (!self.attachments){
|
||||
self.attachments = [NSArray array];
|
||||
}
|
||||
self.attachments = [self.attachments arrayByAddingObject:object];
|
||||
}
|
||||
@end
|
||||
|
@ -35,6 +35,7 @@
|
||||
@property (nonatomic, copy) NSNumber *id;
|
||||
@property (nonatomic, copy) NSString *originalFilename;
|
||||
@property (nonatomic, copy) NSString *contentType;
|
||||
@property (nonatomic, copy) NSString *sourceURL;
|
||||
@property (nonatomic, readonly) NSData *data;
|
||||
|
||||
@property (readonly) UIImage *imageRepresentation;
|
||||
@ -48,4 +49,6 @@
|
||||
|
||||
- (void)deleteContents;
|
||||
|
||||
-(BOOL)needsLoadingFromURL;
|
||||
|
||||
@end
|
||||
|
@ -39,6 +39,7 @@
|
||||
@property (nonatomic, strong) NSData *internalData;
|
||||
@property (nonatomic, copy) NSString *filename;
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@implementation BITFeedbackMessageAttachment
|
||||
@ -92,12 +93,18 @@
|
||||
self.thumbnailRepresentations = [NSMutableDictionary new];
|
||||
}
|
||||
|
||||
-(BOOL)needsLoadingFromURL {
|
||||
return (self.sourceURL);
|
||||
}
|
||||
|
||||
#pragma mark NSCoding
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder {
|
||||
[aCoder encodeObject:self.contentType forKey:@"contentType"];
|
||||
[aCoder encodeObject:self.filename forKey:@"filename"];
|
||||
[aCoder encodeObject:self.originalFilename forKey:@"originalFilename"];
|
||||
[aCoder encodeObject:self.sourceURL forKey:@"url"];
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -109,6 +116,8 @@
|
||||
self.filename = [aDecoder decodeObjectForKey:@"filename"];
|
||||
self.thumbnailRepresentations = [NSMutableDictionary new];
|
||||
self.originalFilename = [aDecoder decodeObjectForKey:@"originalFilename"];
|
||||
self.sourceURL = [aDecoder decodeObjectForKey:@"sourceURL"];
|
||||
|
||||
}
|
||||
|
||||
return self;
|
||||
@ -117,7 +126,7 @@
|
||||
#pragma mark - Thubmnails / Image Representation
|
||||
|
||||
- (UIImage *)imageRepresentation {
|
||||
if ([self.contentType rangeOfString:@"image"].location != NSNotFound){
|
||||
if ([self.contentType rangeOfString:@"image"].location != NSNotFound || [self.sourceURL rangeOfString:@"jpeg"].location != NSNotFound){
|
||||
return [UIImage imageWithData:self.data];
|
||||
} else {
|
||||
return bit_imageNamed(@"feedbackActiviy.png", BITHOCKEYSDK_BUNDLE); // TODO add another placeholder.
|
||||
|
Loading…
x
Reference in New Issue
Block a user