mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
MessagesVC: Paging and fix scrolling bug.
Reviewed-by: @FredericJacobs
This commit is contained in:
parent
9ae4a435a1
commit
ee07490d3e
|
@ -505,6 +505,7 @@
|
||||||
FC4FA0331A1D46AE00DA100A /* InitialViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC4FA0321A1D46AE00DA100A /* InitialViewController.m */; };
|
FC4FA0331A1D46AE00DA100A /* InitialViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FC4FA0321A1D46AE00DA100A /* InitialViewController.m */; };
|
||||||
FC5CDF391A3393DD00B47253 /* error_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC5CDF371A3393DD00B47253 /* error_white@2x.png */; };
|
FC5CDF391A3393DD00B47253 /* error_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC5CDF371A3393DD00B47253 /* error_white@2x.png */; };
|
||||||
FC5CDF3A1A3393DD00B47253 /* warning_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC5CDF381A3393DD00B47253 /* warning_white@2x.png */; };
|
FC5CDF3A1A3393DD00B47253 /* warning_white@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC5CDF381A3393DD00B47253 /* warning_white@2x.png */; };
|
||||||
|
FC7C7A961A581AF40091823B /* TSAdapterCacheManager.m in Sources */ = {isa = PBXBuildFile; fileRef = FC7C7A951A581AF40091823B /* TSAdapterCacheManager.m */; };
|
||||||
FC9120411A39EFB70074545C /* qr@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC91203F1A39EFB70074545C /* qr@2x.png */; };
|
FC9120411A39EFB70074545C /* qr@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC91203F1A39EFB70074545C /* qr@2x.png */; };
|
||||||
FC9120431A39F9E00074545C /* qr_scan_fingerprint@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC9120421A39F9E00074545C /* qr_scan_fingerprint@2x.png */; };
|
FC9120431A39F9E00074545C /* qr_scan_fingerprint@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FC9120421A39F9E00074545C /* qr_scan_fingerprint@2x.png */; };
|
||||||
FCA52AE61A2B676C00CCADFA /* call_canceled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCA52ADE1A2B676C00CCADFA /* call_canceled@2x.png */; };
|
FCA52AE61A2B676C00CCADFA /* call_canceled@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = FCA52ADE1A2B676C00CCADFA /* call_canceled@2x.png */; };
|
||||||
|
@ -1211,6 +1212,8 @@
|
||||||
FC4FA0321A1D46AE00DA100A /* InitialViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InitialViewController.m; sourceTree = "<group>"; };
|
FC4FA0321A1D46AE00DA100A /* InitialViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InitialViewController.m; sourceTree = "<group>"; };
|
||||||
FC5CDF371A3393DD00B47253 /* error_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "error_white@2x.png"; sourceTree = "<group>"; };
|
FC5CDF371A3393DD00B47253 /* error_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "error_white@2x.png"; sourceTree = "<group>"; };
|
||||||
FC5CDF381A3393DD00B47253 /* warning_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "warning_white@2x.png"; sourceTree = "<group>"; };
|
FC5CDF381A3393DD00B47253 /* warning_white@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "warning_white@2x.png"; sourceTree = "<group>"; };
|
||||||
|
FC7C7A941A581AF40091823B /* TSAdapterCacheManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSAdapterCacheManager.h; sourceTree = "<group>"; };
|
||||||
|
FC7C7A951A581AF40091823B /* TSAdapterCacheManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAdapterCacheManager.m; sourceTree = "<group>"; };
|
||||||
FC91203F1A39EFB70074545C /* qr@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "qr@2x.png"; sourceTree = "<group>"; };
|
FC91203F1A39EFB70074545C /* qr@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "qr@2x.png"; sourceTree = "<group>"; };
|
||||||
FC9120421A39F9E00074545C /* qr_scan_fingerprint@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "qr_scan_fingerprint@2x.png"; sourceTree = "<group>"; };
|
FC9120421A39F9E00074545C /* qr_scan_fingerprint@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "qr_scan_fingerprint@2x.png"; sourceTree = "<group>"; };
|
||||||
FCA52ADE1A2B676C00CCADFA /* call_canceled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_canceled@2x.png"; sourceTree = "<group>"; };
|
FCA52ADE1A2B676C00CCADFA /* call_canceled@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "call_canceled@2x.png"; sourceTree = "<group>"; };
|
||||||
|
@ -1833,6 +1836,8 @@
|
||||||
76EB04FD18170B33006006FC /* Zid.m */,
|
76EB04FD18170B33006006FC /* Zid.m */,
|
||||||
FCC81A961A44558300DFEC7D /* UIDevice+TSHardwareVersion.h */,
|
FCC81A961A44558300DFEC7D /* UIDevice+TSHardwareVersion.h */,
|
||||||
FCC81A971A44558300DFEC7D /* UIDevice+TSHardwareVersion.m */,
|
FCC81A971A44558300DFEC7D /* UIDevice+TSHardwareVersion.m */,
|
||||||
|
FC7C7A941A581AF40091823B /* TSAdapterCacheManager.h */,
|
||||||
|
FC7C7A951A581AF40091823B /* TSAdapterCacheManager.m */,
|
||||||
);
|
);
|
||||||
path = util;
|
path = util;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -3272,6 +3277,7 @@
|
||||||
7038632718F70C0700D4A43F /* CryptoTools.m in Sources */,
|
7038632718F70C0700D4A43F /* CryptoTools.m in Sources */,
|
||||||
76EB058C18170B33006006FC /* DnsManager.m in Sources */,
|
76EB058C18170B33006006FC /* DnsManager.m in Sources */,
|
||||||
B63AF5CB1A1F757900D01AAD /* TSRegisterPrekeysRequest.m in Sources */,
|
B63AF5CB1A1F757900D01AAD /* TSRegisterPrekeysRequest.m in Sources */,
|
||||||
|
FC7C7A961A581AF40091823B /* TSAdapterCacheManager.m in Sources */,
|
||||||
B6FAAAE81A41BC6C007FEC1D /* TSAttachmentPointer.m in Sources */,
|
B6FAAAE81A41BC6C007FEC1D /* TSAttachmentPointer.m in Sources */,
|
||||||
B6B096881A1D25ED008BFAA6 /* TSStorageManager+keyFromIntLong.m in Sources */,
|
B6B096881A1D25ED008BFAA6 /* TSStorageManager+keyFromIntLong.m in Sources */,
|
||||||
B6B50AAB1A4192C500F8F607 /* TSMessagesManager+attachments.m in Sources */,
|
B6B50AAB1A4192C500F8F607 /* TSMessagesManager+attachments.m in Sources */,
|
||||||
|
|
27
Signal/src/util/TSAdapterCacheManager.h
Normal file
27
Signal/src/util/TSAdapterCacheManager.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// TSAdapterCacheManager.h
|
||||||
|
// Signal
|
||||||
|
//
|
||||||
|
// Created by Dylan Bourgeois on 03/01/15.
|
||||||
|
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
@class TSMessageAdapter;
|
||||||
|
|
||||||
|
@interface TSAdapterCacheManager : NSObject {
|
||||||
|
NSCache * messageAdaptersCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property (nonatomic, retain) NSCache *messageAdaptersCache;
|
||||||
|
|
||||||
|
+ (id)sharedManager;
|
||||||
|
|
||||||
|
- (void)cacheAdapter:(TSMessageAdapter*)adapter forInteractionId:(NSString*)identifier;
|
||||||
|
- (void)clearCacheEntryForInteractionId:(NSString*)identifier;
|
||||||
|
- (TSMessageAdapter*)adapterForInteractionId:(NSString*)identifier;
|
||||||
|
- (BOOL)containsCacheEntryForInteractionId:(NSString*)identifier;
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
58
Signal/src/util/TSAdapterCacheManager.m
Normal file
58
Signal/src/util/TSAdapterCacheManager.m
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
//
|
||||||
|
// TSAdapterCacheManager.m
|
||||||
|
// Signal
|
||||||
|
//
|
||||||
|
// Created by Dylan Bourgeois on 03/01/15.
|
||||||
|
// Copyright (c) 2015 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "TSAdapterCacheManager.h"
|
||||||
|
#import "TSMessageAdapter.h"
|
||||||
|
|
||||||
|
@implementation TSAdapterCacheManager
|
||||||
|
|
||||||
|
@synthesize messageAdaptersCache;
|
||||||
|
|
||||||
|
+ (id)sharedManager {
|
||||||
|
static TSAdapterCacheManager *sharedManager = nil;
|
||||||
|
static dispatch_once_t onceToken;
|
||||||
|
|
||||||
|
dispatch_once(&onceToken, ^{
|
||||||
|
sharedManager = [[self alloc] init];
|
||||||
|
});
|
||||||
|
|
||||||
|
return sharedManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)init {
|
||||||
|
if (self = [super init]) {
|
||||||
|
messageAdaptersCache = [[NSCache alloc]init];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)cacheAdapter:(TSMessageAdapter*)adapter forInteractionId:(NSString*)identifier
|
||||||
|
{
|
||||||
|
NSParameterAssert(adapter);
|
||||||
|
NSParameterAssert(identifier);
|
||||||
|
[messageAdaptersCache setObject:adapter forKey:identifier];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)clearCacheEntryForInteractionId:(NSString*)identifier
|
||||||
|
{
|
||||||
|
NSParameterAssert(identifier);
|
||||||
|
[messageAdaptersCache removeObjectForKey:identifier];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(TSMessageAdapter*)adapterForInteractionId:(NSString*)identifier
|
||||||
|
{
|
||||||
|
NSParameterAssert(identifier);
|
||||||
|
return [messageAdaptersCache objectForKey:identifier];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(BOOL)containsCacheEntryForInteractionId:(NSString*)identifier
|
||||||
|
{
|
||||||
|
return [messageAdaptersCache objectForKey:identifier] != nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -54,6 +54,12 @@
|
||||||
#import "ContactsManager.h"
|
#import "ContactsManager.h"
|
||||||
#import "PreferencesUtil.h"
|
#import "PreferencesUtil.h"
|
||||||
|
|
||||||
|
#import "TSAdapterCacheManager.h"
|
||||||
|
|
||||||
|
#define kYapDatabaseRangeLength 50
|
||||||
|
#define kYapDatabaseRangeMaxLength 300
|
||||||
|
#define kYapDatabaseRangeMinLength 20
|
||||||
|
|
||||||
static NSTimeInterval const kTSMessageSentDateShowTimeInterval = 5 * 60;
|
static NSTimeInterval const kTSMessageSentDateShowTimeInterval = 5 * 60;
|
||||||
static NSString *const kUpdateGroupSegueIdentifier = @"updateGroupSegue";
|
static NSString *const kUpdateGroupSegueIdentifier = @"updateGroupSegue";
|
||||||
static NSString *const kFingerprintSegueIdentifier = @"fingerprintSegue";
|
static NSString *const kFingerprintSegueIdentifier = @"fingerprintSegue";
|
||||||
|
@ -82,6 +88,8 @@ typedef enum : NSUInteger {
|
||||||
|
|
||||||
@property (nonatomic, retain) NSIndexPath *lastDeliveredMessageIndexPath;
|
@property (nonatomic, retain) NSIndexPath *lastDeliveredMessageIndexPath;
|
||||||
|
|
||||||
|
@property NSUInteger page;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MessagesViewController
|
@implementation MessagesViewController
|
||||||
|
@ -115,6 +123,7 @@ typedef enum : NSUInteger {
|
||||||
|
|
||||||
- (void)viewDidLoad {
|
- (void)viewDidLoad {
|
||||||
[super viewDidLoad];
|
[super viewDidLoad];
|
||||||
|
|
||||||
[self markAllMessagesAsRead];
|
[self markAllMessagesAsRead];
|
||||||
|
|
||||||
[self initializeBubbles];
|
[self initializeBubbles];
|
||||||
|
@ -122,14 +131,17 @@ typedef enum : NSUInteger {
|
||||||
self.messageMappings = [[YapDatabaseViewMappings alloc] initWithGroups:@[self.thread.uniqueId]
|
self.messageMappings = [[YapDatabaseViewMappings alloc] initWithGroups:@[self.thread.uniqueId]
|
||||||
view:TSMessageDatabaseViewExtensionName];
|
view:TSMessageDatabaseViewExtensionName];
|
||||||
|
|
||||||
|
self.page = 0;
|
||||||
|
|
||||||
|
[self updateRangeOptionsForPage:self.page];
|
||||||
|
|
||||||
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||||
[self.messageMappings updateWithTransaction:transaction];
|
[self.messageMappings updateWithTransaction:transaction];
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[self initializeToolbars];
|
[self initializeToolbars];
|
||||||
[self initializeCollectionViewLayout];
|
[self initializeCollectionViewLayout];
|
||||||
|
|
||||||
|
|
||||||
self.senderId = ME_MESSAGE_IDENTIFIER
|
self.senderId = ME_MESSAGE_IDENTIFIER
|
||||||
self.senderDisplayName = ME_MESSAGE_IDENTIFIER
|
self.senderDisplayName = ME_MESSAGE_IDENTIFIER
|
||||||
|
|
||||||
|
@ -142,8 +154,10 @@ typedef enum : NSUInteger {
|
||||||
-(void)viewWillAppear:(BOOL)animated
|
-(void)viewWillAppear:(BOOL)animated
|
||||||
{
|
{
|
||||||
[super viewWillAppear:animated];
|
[super viewWillAppear:animated];
|
||||||
self.automaticallyScrollsToMostRecentMessage = YES;
|
|
||||||
[self scrollToBottomAnimated:NO];
|
NSIndexPath * lastCellIndexPath = [NSIndexPath indexPathForRow:(NSInteger)[self.messageMappings numberOfItemsInGroup:self.thread.uniqueId]-1 inSection:0];
|
||||||
|
[self.collectionView scrollToItemAtIndexPath:lastCellIndexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)startReadTimer{
|
- (void)startReadTimer{
|
||||||
|
@ -157,7 +171,6 @@ typedef enum : NSUInteger {
|
||||||
- (void)viewDidAppear:(BOOL)animated{
|
- (void)viewDidAppear:(BOOL)animated{
|
||||||
[super viewDidAppear:animated];
|
[super viewDidAppear:animated];
|
||||||
[self startReadTimer];
|
[self startReadTimer];
|
||||||
[self scrollToBottomAnimated:YES];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)viewWillDisappear:(BOOL)animated{
|
- (void)viewWillDisappear:(BOOL)animated{
|
||||||
|
@ -219,7 +232,7 @@ typedef enum : NSUInteger {
|
||||||
self.collectionView.showsVerticalScrollIndicator = NO;
|
self.collectionView.showsVerticalScrollIndicator = NO;
|
||||||
self.collectionView.showsHorizontalScrollIndicator = NO;
|
self.collectionView.showsHorizontalScrollIndicator = NO;
|
||||||
|
|
||||||
self.automaticallyScrollsToMostRecentMessage = NO;
|
[self updateLoadEarlierVisible];
|
||||||
|
|
||||||
self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero;
|
self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero;
|
||||||
self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;
|
self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero;
|
||||||
|
@ -426,7 +439,7 @@ typedef enum : NSUInteger {
|
||||||
|
|
||||||
-(BOOL)shouldShowMessageStatusAtIndexPath:(NSIndexPath*)indexPath
|
-(BOOL)shouldShowMessageStatusAtIndexPath:(NSIndexPath*)indexPath
|
||||||
{
|
{
|
||||||
|
|
||||||
TSMessageAdapter *currentMessage = [self messageAtIndexPath:indexPath];
|
TSMessageAdapter *currentMessage = [self messageAtIndexPath:indexPath];
|
||||||
if([self.thread isKindOfClass:[TSGroupThread class]]) {
|
if([self.thread isKindOfClass:[TSGroupThread class]]) {
|
||||||
return currentMessage.messageType == TSIncomingMessageAdapter;
|
return currentMessage.messageType == TSIncomingMessageAdapter;
|
||||||
|
@ -513,8 +526,7 @@ typedef enum : NSUInteger {
|
||||||
{
|
{
|
||||||
TSMessageAdapter *messageItem = [collectionView.dataSource collectionView:collectionView messageDataForItemAtIndexPath:indexPath];
|
TSMessageAdapter *messageItem = [collectionView.dataSource collectionView:collectionView messageDataForItemAtIndexPath:indexPath];
|
||||||
TSInteraction *interaction = [self interactionAtIndexPath:indexPath];
|
TSInteraction *interaction = [self interactionAtIndexPath:indexPath];
|
||||||
|
|
||||||
|
|
||||||
switch (messageItem.messageType) {
|
switch (messageItem.messageType) {
|
||||||
case TSOutgoingMessageAdapter:
|
case TSOutgoingMessageAdapter:
|
||||||
if (messageItem.messageState == TSOutgoingMessageStateUnsent) {
|
if (messageItem.messageState == TSOutgoingMessageStateUnsent) {
|
||||||
|
@ -558,6 +570,81 @@ typedef enum : NSUInteger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(void)collectionView:(JSQMessagesCollectionView *)collectionView header:(JSQMessagesLoadEarlierHeaderView *)headerView didTapLoadEarlierMessagesButton:(UIButton *)sender
|
||||||
|
{
|
||||||
|
if ([self shouldShowLoadEarlierMessages]) {
|
||||||
|
self.page++;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSInteger item = (NSInteger)[self scrollToItem];
|
||||||
|
|
||||||
|
[self updateRangeOptionsForPage:self.page];
|
||||||
|
|
||||||
|
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||||
|
[self.messageMappings updateWithTransaction:transaction];
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self updateLayoutForEarlierMessagesWithOffset:item];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
-(BOOL)shouldShowLoadEarlierMessages
|
||||||
|
{
|
||||||
|
__block BOOL show = YES;
|
||||||
|
|
||||||
|
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction){
|
||||||
|
show = [self.messageMappings numberOfItemsInGroup:self.thread.uniqueId] < [[transaction ext:TSMessageDatabaseViewExtensionName] numberOfItemsInGroup:self.thread.uniqueId];
|
||||||
|
}];
|
||||||
|
|
||||||
|
return show;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSUInteger)scrollToItem
|
||||||
|
{
|
||||||
|
__block NSUInteger item = kYapDatabaseRangeLength*(self.page+1) - [self.messageMappings numberOfItemsInGroup:self.thread.uniqueId];
|
||||||
|
|
||||||
|
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||||
|
|
||||||
|
NSUInteger numberOfVisibleMessages = [self.messageMappings numberOfItemsInGroup:self.thread.uniqueId] ;
|
||||||
|
NSUInteger numberOfTotalMessages = [[transaction ext:TSMessageDatabaseViewExtensionName] numberOfItemsInGroup:self.thread.uniqueId] ;
|
||||||
|
NSUInteger numberOfMessagesToLoad = numberOfTotalMessages - numberOfVisibleMessages ;
|
||||||
|
|
||||||
|
BOOL canLoadFullRange = numberOfMessagesToLoad >= kYapDatabaseRangeLength;
|
||||||
|
|
||||||
|
if (!canLoadFullRange) {
|
||||||
|
item = numberOfMessagesToLoad;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
return item == 0 ? item : item - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)updateLoadEarlierVisible
|
||||||
|
{
|
||||||
|
[self setShowLoadEarlierMessagesHeader:[self shouldShowLoadEarlierMessages]];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)updateLayoutForEarlierMessagesWithOffset:(NSInteger)offset
|
||||||
|
{
|
||||||
|
[self.collectionView.collectionViewLayout invalidateLayoutWithContext:[JSQMessagesCollectionViewFlowLayoutInvalidationContext context]];
|
||||||
|
[self.collectionView reloadData];
|
||||||
|
|
||||||
|
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:offset inSection:0] atScrollPosition:UICollectionViewScrollPositionTop animated:NO];
|
||||||
|
|
||||||
|
[self updateLoadEarlierVisible];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)updateRangeOptionsForPage:(NSUInteger)page
|
||||||
|
{
|
||||||
|
YapDatabaseViewRangeOptions *rangeOptions = [YapDatabaseViewRangeOptions flexibleRangeWithLength:kYapDatabaseRangeLength*(page+1) offset:0 from:YapDatabaseViewEnd];
|
||||||
|
|
||||||
|
rangeOptions.maxLength = kYapDatabaseRangeMaxLength;
|
||||||
|
rangeOptions.minLength = kYapDatabaseRangeMinLength;
|
||||||
|
|
||||||
|
[self.messageMappings setRangeOptions:rangeOptions forGroup:self.thread.uniqueId];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark Bubble User Actions
|
#pragma mark Bubble User Actions
|
||||||
|
|
||||||
- (void)handleUnsentMessageTap:(TSOutgoingMessage*)message{
|
- (void)handleUnsentMessageTap:(TSOutgoingMessage*)message{
|
||||||
|
@ -823,48 +910,65 @@ typedef enum : NSUInteger {
|
||||||
forNotifications:notifications
|
forNotifications:notifications
|
||||||
withMappings:self.messageMappings];
|
withMappings:self.messageMappings];
|
||||||
|
|
||||||
|
__block BOOL containsInsertion = NO;
|
||||||
|
|
||||||
if (!messageRowChanges) {
|
if (!messageRowChanges) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[self.collectionView performBatchUpdates:^{
|
[self.collectionView performBatchUpdates:^{
|
||||||
|
|
||||||
for (YapDatabaseViewRowChange *rowChange in messageRowChanges)
|
for (YapDatabaseViewRowChange *rowChange in messageRowChanges)
|
||||||
{
|
{
|
||||||
switch (rowChange.type)
|
switch (rowChange.type)
|
||||||
{
|
{
|
||||||
case YapDatabaseViewChangeDelete :
|
case YapDatabaseViewChangeDelete :
|
||||||
{
|
{
|
||||||
|
TSInteraction * interaction = [self interactionAtIndexPath:rowChange.indexPath];
|
||||||
|
[[TSAdapterCacheManager sharedManager] clearCacheEntryForInteractionId:interaction.uniqueId];
|
||||||
[self.collectionView deleteItemsAtIndexPaths:@[ rowChange.indexPath ]];
|
[self.collectionView deleteItemsAtIndexPaths:@[ rowChange.indexPath ]];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case YapDatabaseViewChangeInsert :
|
case YapDatabaseViewChangeInsert :
|
||||||
{
|
{
|
||||||
|
TSInteraction * interaction = [self interactionAtIndexPath:rowChange.newIndexPath];
|
||||||
|
[[TSAdapterCacheManager sharedManager] cacheAdapter:[TSMessageAdapter messageViewDataWithInteraction:interaction inThread:self.thread] forInteractionId:interaction.uniqueId];
|
||||||
[self.collectionView insertItemsAtIndexPaths:@[ rowChange.newIndexPath ]];
|
[self.collectionView insertItemsAtIndexPaths:@[ rowChange.newIndexPath ]];
|
||||||
|
containsInsertion = YES;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case YapDatabaseViewChangeMove :
|
case YapDatabaseViewChangeMove :
|
||||||
{
|
{
|
||||||
[self.collectionView deleteItemsAtIndexPaths:@[ rowChange.indexPath]];
|
[self.collectionView deleteItemsAtIndexPaths:@[ rowChange.indexPath ]];
|
||||||
[self.collectionView insertItemsAtIndexPaths:@[ rowChange.newIndexPath]];
|
[self.collectionView insertItemsAtIndexPaths:@[ rowChange.newIndexPath ]];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case YapDatabaseViewChangeUpdate :
|
case YapDatabaseViewChangeUpdate :
|
||||||
{
|
{
|
||||||
NSMutableArray *rowsToUpdate = [@[rowChange.indexPath] mutableCopy];
|
NSMutableArray *rowsToUpdate = [@[rowChange.indexPath] mutableCopy];
|
||||||
|
|
||||||
if (_lastDeliveredMessageIndexPath) {
|
if (_lastDeliveredMessageIndexPath) {
|
||||||
[rowsToUpdate addObject:_lastDeliveredMessageIndexPath];
|
[rowsToUpdate addObject:_lastDeliveredMessageIndexPath];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (NSIndexPath* indexPath in rowsToUpdate) {
|
||||||
|
TSInteraction * interaction = [self interactionAtIndexPath:indexPath];
|
||||||
|
[[TSAdapterCacheManager sharedManager] cacheAdapter:[TSMessageAdapter messageViewDataWithInteraction:interaction inThread:self.thread] forInteractionId:interaction.uniqueId];
|
||||||
|
}
|
||||||
|
|
||||||
[self.collectionView reloadItemsAtIndexPaths:rowsToUpdate];
|
[self.collectionView reloadItemsAtIndexPaths:rowsToUpdate];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} completion:^(BOOL success) {
|
||||||
} completion:^(BOOL finished) {
|
if (success) {
|
||||||
[self scrollToBottomAnimated:YES];
|
[self.collectionView.collectionViewLayout invalidateLayoutWithContext:[JSQMessagesCollectionViewFlowLayoutInvalidationContext context]];
|
||||||
|
[self.collectionView reloadData];
|
||||||
|
}
|
||||||
|
if (containsInsertion) {
|
||||||
|
[self scrollToBottomAnimated:YES];
|
||||||
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -897,8 +1001,16 @@ typedef enum : NSUInteger {
|
||||||
|
|
||||||
- (TSMessageAdapter*)messageAtIndexPath:(NSIndexPath *)indexPath {
|
- (TSMessageAdapter*)messageAtIndexPath:(NSIndexPath *)indexPath {
|
||||||
TSInteraction *interaction = [self interactionAtIndexPath:indexPath];
|
TSInteraction *interaction = [self interactionAtIndexPath:indexPath];
|
||||||
return [TSMessageAdapter messageViewDataWithInteraction:interaction inThread:self.thread];
|
TSAdapterCacheManager * manager = [TSAdapterCacheManager sharedManager];
|
||||||
|
|
||||||
|
if (![manager containsCacheEntryForInteractionId:interaction.uniqueId]) {
|
||||||
|
[manager cacheAdapter:[TSMessageAdapter messageViewDataWithInteraction:interaction inThread:self.thread] forInteractionId:interaction.uniqueId];
|
||||||
|
}
|
||||||
|
|
||||||
|
return [manager adapterForInteractionId:interaction.uniqueId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark group action view
|
#pragma mark group action view
|
||||||
-(void)didPressGroupMenuButton:(UIButton *)sender
|
-(void)didPressGroupMenuButton:(UIButton *)sender
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue