Fixes #404
Support for drafts. Unsent messages are saved in case you want to send them later on and were interrupted while redacting them.
This commit is contained in:
parent
daac2c0db3
commit
ee62cbdf23
|
@ -11,28 +11,6 @@
|
|||
|
||||
@class TSInteraction;
|
||||
|
||||
typedef NS_ENUM(NSInteger, TSLastActionType) {
|
||||
TSLastActionNone,
|
||||
|
||||
TSLastActionCallIncoming,
|
||||
TSLastActionCallIncomingMissed,
|
||||
|
||||
TSLastActionCallOutgoing,
|
||||
TSLastActionCallOutgoingMissed,
|
||||
TSLastActionCallOutgoingFailed,
|
||||
|
||||
TSLastActionMessageAttemptingOut,
|
||||
TSLastActionMessageUnsent,
|
||||
TSLastActionMessageSent,
|
||||
TSLastActionMessageDelivered,
|
||||
|
||||
TSLastActionMessageIncomingRead,
|
||||
TSLastActionMessageIncomingUnread,
|
||||
|
||||
TSLastActionInfoMessage,
|
||||
TSLastActionErrorMessage
|
||||
};
|
||||
|
||||
/**
|
||||
* TSThread is the superclass of TSContactThread and TSGroupThread
|
||||
*/
|
||||
|
@ -40,45 +18,112 @@ typedef NS_ENUM(NSInteger, TSLastActionType) {
|
|||
@interface TSThread : TSYapDatabaseObject
|
||||
|
||||
/**
|
||||
* Returns whether the object is a group thread or not
|
||||
* Whether the object is a group thread or not.
|
||||
*
|
||||
* @return Is a group
|
||||
* @return YES if is a group thread, NO otherwise.
|
||||
*/
|
||||
|
||||
- (BOOL)isGroupThread;
|
||||
|
||||
/**
|
||||
* Returns the name of the thread.
|
||||
*
|
||||
* @return name of the thread
|
||||
* @return The name of the thread.
|
||||
*/
|
||||
|
||||
- (NSString*)name;
|
||||
- (NSString *)name;
|
||||
|
||||
/**
|
||||
* Returns the image representing the thread. Nil if not available.
|
||||
*
|
||||
* @return UIImage of the thread, or nil.
|
||||
*/
|
||||
- (UIImage *)image;
|
||||
|
||||
#pragma mark Read Status
|
||||
|
||||
- (UIImage*)image;
|
||||
|
||||
- (NSDate*)lastMessageDate;
|
||||
- (NSString*)lastMessageLabel;
|
||||
- (NSDate*)archivalDate;
|
||||
|
||||
- (void)updateWithLastMessage:(TSInteraction*)lastMessage transaction:(YapDatabaseReadWriteTransaction*)transaction;
|
||||
|
||||
- (TSLastActionType)lastAction;
|
||||
|
||||
/**
|
||||
* Returns whether or not the thread has unread messages.
|
||||
*
|
||||
* @return YES if it has unread TSIncomingMessages, NO otherwise.
|
||||
*/
|
||||
- (BOOL)hasUnreadMessages;
|
||||
|
||||
- (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction*)transaction;
|
||||
- (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||
|
||||
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction*)transaction;
|
||||
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction*)transaction referenceDate:(NSDate*)date;
|
||||
#pragma mark Last Interactions
|
||||
|
||||
- (void)unarchiveThreadWithTransaction:(YapDatabaseReadWriteTransaction*)transaction;
|
||||
/**
|
||||
* Returns the latest date of a message in the thread or the thread creation date if there are no messages in that
|
||||
*thread.
|
||||
*
|
||||
* @return The date of the last message or thread creation date.
|
||||
*/
|
||||
- (NSDate *)lastMessageDate;
|
||||
|
||||
/**
|
||||
* Returns the string that will be displayed typically in a conversations view as a preview of the last message
|
||||
*received in this thread.
|
||||
*
|
||||
* @return Thread preview string.
|
||||
*/
|
||||
- (NSString *)lastMessageLabel;
|
||||
|
||||
/**
|
||||
* Updates the thread's caches of the latest interaction.
|
||||
*
|
||||
* @param lastMessage Latest Interaction to take into consideration.
|
||||
* @param transaction Database transaction.
|
||||
*/
|
||||
- (void)updateWithLastMessage:(TSInteraction *)lastMessage transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||
|
||||
#pragma mark Archival
|
||||
|
||||
/**
|
||||
* Returns the last date at which a string was archived or nil if the thread was never archived or brought back to the
|
||||
*inbox.
|
||||
*
|
||||
* @return Last archival date.
|
||||
*/
|
||||
- (NSDate *)archivalDate;
|
||||
|
||||
/**
|
||||
* Archives a thread with the current date.
|
||||
*
|
||||
* @param transaction Database transaction.
|
||||
*/
|
||||
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||
|
||||
/**
|
||||
* Archives a thread with the reference date. This is currently only used for migrating older data that has already been archived.
|
||||
*
|
||||
* @param transaction Database transaction.
|
||||
* @param date Date at which the thread was archived.
|
||||
*/
|
||||
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction referenceDate:(NSDate *)date;
|
||||
|
||||
/**
|
||||
* Unarchives a thread that was archived previously.
|
||||
*
|
||||
* @param transaction Database transaction.
|
||||
*/
|
||||
- (void)unarchiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||
|
||||
#pragma mark Drafts
|
||||
|
||||
/**
|
||||
* Returns the last known draft for that thread. Always returns a string. Empty string if nil.
|
||||
*
|
||||
* @param transaction Database transaction.
|
||||
*
|
||||
* @return Last known draft for that thread.
|
||||
*/
|
||||
- (NSString *)currentDraftWithTransaction:(YapDatabaseReadTransaction *)transaction;
|
||||
|
||||
/**
|
||||
* Sets the draft of a thread. Typically called when leaving a conversation view.
|
||||
*
|
||||
* @param draftString Draft string to be saved.
|
||||
* @param transaction Database transaction.
|
||||
*/
|
||||
- (void)setDraft:(NSString *)draftString transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||
|
||||
@end
|
||||
|
|
|
@ -21,37 +21,89 @@
|
|||
@interface TSThread ()
|
||||
|
||||
@property (nonatomic, retain) NSDate *creationDate;
|
||||
@property (nonatomic, copy) NSDate *archivalDate;
|
||||
@property (nonatomic, copy ) NSDate *archivalDate;
|
||||
@property (nonatomic, retain) NSDate *lastMessageDate;
|
||||
@property (nonatomic, copy ) NSString *latestMessageId;
|
||||
|
||||
@property (nonatomic, copy ) NSString *messageDraft;
|
||||
@end
|
||||
|
||||
@implementation TSThread
|
||||
|
||||
+ (NSString *)collection{
|
||||
+ (NSString *)collection
|
||||
{
|
||||
return @"TSThread";
|
||||
}
|
||||
|
||||
- (instancetype)initWithUniqueId:(NSString *)uniqueId{
|
||||
- (instancetype)initWithUniqueId:(NSString *)uniqueId
|
||||
{
|
||||
self = [super initWithUniqueId:uniqueId];
|
||||
|
||||
|
||||
if (self) {
|
||||
_archivalDate = nil;
|
||||
_latestMessageId = nil;
|
||||
_lastMessageDate = nil;
|
||||
_creationDate = [NSDate date];
|
||||
_messageDraft = nil;
|
||||
}
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isGroupThread{
|
||||
#pragma mark To be subclassed.
|
||||
|
||||
- (BOOL)isGroupThread
|
||||
{
|
||||
NSAssert(false, @"An abstract method on TSThread was called.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- (NSDate *)lastMessageDate{
|
||||
- (NSString *)name
|
||||
{
|
||||
NSAssert(FALSE, @"Should be implemented in subclasses");
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (UIImage *)image
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark Read Status
|
||||
|
||||
- (BOOL)hasUnreadMessages
|
||||
{
|
||||
__block TSInteraction *interaction;
|
||||
__block BOOL hasUnread = NO;
|
||||
[[TSStorageManager sharedManager].dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
interaction = [TSInteraction fetchObjectWithUniqueID:self.latestMessageId transaction:transaction];
|
||||
if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
|
||||
hasUnread = ![(TSIncomingMessage *)interaction wasRead];
|
||||
}
|
||||
}];
|
||||
|
||||
return hasUnread;
|
||||
}
|
||||
|
||||
- (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSUnreadDatabaseViewExtensionName];
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
[viewTransaction enumerateRowsInGroup:self.uniqueId
|
||||
usingBlock:^(NSString *collection, NSString *key, id object, id metadata,
|
||||
NSUInteger index, BOOL *stop) {
|
||||
[array addObject:object];
|
||||
}];
|
||||
|
||||
for (TSIncomingMessage *message in array) {
|
||||
message.read = YES;
|
||||
[message saveWithTransaction:transaction];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark Last Interactions
|
||||
|
||||
- (NSDate *)lastMessageDate
|
||||
{
|
||||
if (_lastMessageDate) {
|
||||
return _lastMessageDate;
|
||||
} else {
|
||||
|
@ -59,128 +111,68 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (UIImage*)image{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSDate *)archivalDate{
|
||||
return _archivalDate;
|
||||
}
|
||||
|
||||
- (NSString*)lastMessageLabel{
|
||||
- (NSString *)lastMessageLabel
|
||||
{
|
||||
__block TSInteraction *interaction;
|
||||
[[TSStorageManager sharedManager].dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
interaction = [TSInteraction fetchObjectWithUniqueID:self.latestMessageId transaction:transaction];
|
||||
interaction = [TSInteraction fetchObjectWithUniqueID:self.latestMessageId transaction:transaction];
|
||||
}];
|
||||
return interaction.description;
|
||||
}
|
||||
|
||||
- (TSLastActionType)lastAction
|
||||
- (void)updateWithLastMessage:(TSInteraction *)lastMessage transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
__block TSInteraction *interaction;
|
||||
[[TSStorageManager sharedManager].dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
interaction = [TSInteraction fetchObjectWithUniqueID:self.latestMessageId transaction:transaction];
|
||||
}];
|
||||
|
||||
return [self lastActionForInteraction:interaction];
|
||||
}
|
||||
|
||||
- (TSLastActionType)lastActionForInteraction:(TSInteraction*)interaction
|
||||
{
|
||||
if ([interaction isKindOfClass:[TSCall class]])
|
||||
{
|
||||
TSCall * callInteraction = (TSCall*)interaction;
|
||||
|
||||
switch (callInteraction.callType) {
|
||||
case RPRecentCallTypeMissed:
|
||||
return TSLastActionCallIncomingMissed;
|
||||
case RPRecentCallTypeIncoming:
|
||||
return TSLastActionCallIncoming;
|
||||
case RPRecentCallTypeOutgoing:
|
||||
return TSLastActionCallOutgoing;
|
||||
default:
|
||||
return TSLastActionNone;
|
||||
}
|
||||
} else if ([interaction isKindOfClass:[TSOutgoingMessage class]]) {
|
||||
TSOutgoingMessage * outgoingMessageInteraction = (TSOutgoingMessage*)interaction;
|
||||
|
||||
switch (outgoingMessageInteraction.messageState) {
|
||||
case TSOutgoingMessageStateAttemptingOut:
|
||||
return TSLastActionNone;
|
||||
case TSOutgoingMessageStateUnsent:
|
||||
return TSLastActionMessageUnsent;
|
||||
case TSOutgoingMessageStateSent:
|
||||
return TSLastActionMessageSent;
|
||||
case TSOutgoingMessageStateDelivered:
|
||||
return TSLastActionMessageDelivered;
|
||||
default:
|
||||
return TSLastActionNone;
|
||||
}
|
||||
|
||||
} else if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
|
||||
return self.hasUnreadMessages ? TSLastActionMessageIncomingUnread : TSLastActionMessageIncomingRead ;
|
||||
} else if ([interaction isKindOfClass:[TSErrorMessage class]]) {
|
||||
return TSLastActionErrorMessage;
|
||||
} else if ([interaction isKindOfClass:[TSInfoMessage class]]) {
|
||||
return TSLastActionInfoMessage;
|
||||
} else {
|
||||
return TSLastActionNone;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)hasUnreadMessages{
|
||||
__block TSInteraction * interaction;
|
||||
__block BOOL hasUnread = NO;
|
||||
[[TSStorageManager sharedManager].dbConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
interaction = [TSInteraction fetchObjectWithUniqueID:self.latestMessageId transaction:transaction];
|
||||
if ([interaction isKindOfClass:[TSIncomingMessage class]]){
|
||||
hasUnread = ![(TSIncomingMessage*)interaction wasRead];
|
||||
}
|
||||
}];
|
||||
|
||||
return hasUnread;
|
||||
}
|
||||
|
||||
- (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction*)transaction {
|
||||
YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSUnreadDatabaseViewExtensionName];
|
||||
NSMutableArray *array = [NSMutableArray array];
|
||||
[viewTransaction enumerateRowsInGroup:self.uniqueId usingBlock:^(NSString *collection, NSString *key, id object, id metadata, NSUInteger index, BOOL *stop) {
|
||||
[array addObject:object];
|
||||
}];
|
||||
|
||||
for (TSIncomingMessage *message in array) {
|
||||
message.read = YES;
|
||||
[message saveWithTransaction:transaction];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction {
|
||||
[self archiveThreadWithTransaction:transaction referenceDate:[NSDate date]];
|
||||
}
|
||||
|
||||
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction*)transaction referenceDate:(NSDate*)date {
|
||||
[self markAllAsReadWithTransaction:transaction];
|
||||
_archivalDate = date;
|
||||
|
||||
[self saveWithTransaction:transaction];
|
||||
}
|
||||
|
||||
- (void)unarchiveThreadWithTransaction:(YapDatabaseReadWriteTransaction*)transaction {
|
||||
_archivalDate = nil;
|
||||
[self saveWithTransaction:transaction];
|
||||
}
|
||||
|
||||
- (void)updateWithLastMessage:(TSInteraction*)lastMessage transaction:(YapDatabaseReadWriteTransaction*)transaction {
|
||||
if (!_lastMessageDate || [lastMessage.date timeIntervalSinceDate:self.lastMessageDate] > 0) {
|
||||
_latestMessageId = lastMessage.uniqueId;
|
||||
_lastMessageDate = lastMessage.date;
|
||||
|
||||
[self saveWithTransaction:transaction];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)name{
|
||||
NSAssert(FALSE, @"Should be implemented in subclasses");
|
||||
return nil;
|
||||
#pragma mark Archival
|
||||
|
||||
- (NSDate *)archivalDate
|
||||
{
|
||||
return _archivalDate;
|
||||
}
|
||||
|
||||
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
[self archiveThreadWithTransaction:transaction referenceDate:[NSDate date]];
|
||||
}
|
||||
|
||||
- (void)archiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction referenceDate:(NSDate *)date
|
||||
{
|
||||
[self markAllAsReadWithTransaction:transaction];
|
||||
_archivalDate = date;
|
||||
|
||||
[self saveWithTransaction:transaction];
|
||||
}
|
||||
|
||||
- (void)unarchiveThreadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
_archivalDate = nil;
|
||||
[self saveWithTransaction:transaction];
|
||||
}
|
||||
|
||||
#pragma mark Drafts
|
||||
|
||||
- (NSString *)currentDraftWithTransaction:(YapDatabaseReadTransaction *)transaction
|
||||
{
|
||||
TSThread *thread = [TSThread fetchObjectWithUniqueID:self.uniqueId transaction:transaction];
|
||||
if (thread.messageDraft) {
|
||||
return thread.messageDraft;
|
||||
} else {
|
||||
return @"";
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setDraft:(NSString *)draftString transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
TSThread *thread = [TSThread fetchObjectWithUniqueID:self.uniqueId transaction:transaction];
|
||||
thread.messageDraft = draftString;
|
||||
[thread saveWithTransaction:transaction];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -11,15 +11,28 @@
|
|||
#import "UIColor+OWS.h"
|
||||
@implementation UIButton (OWS)
|
||||
|
||||
+ (UIButton*) ows_blueButtonWithTitle:(NSString*)title {
|
||||
NSDictionary* buttonTextAttributes = @{NSFontAttributeName:[UIFont ows_regularFontWithSize:15.0f],
|
||||
NSForegroundColorAttributeName:[UIColor ows_materialBlueColor]};
|
||||
UIButton* button = [[UIButton alloc] init];
|
||||
+ (UIButton *)ows_blueButtonWithTitle:(NSString *)title
|
||||
{
|
||||
NSDictionary *buttonTextAttributes = @{
|
||||
NSFontAttributeName : [UIFont ows_regularFontWithSize:15.0f],
|
||||
NSForegroundColorAttributeName : [UIColor ows_materialBlueColor]
|
||||
};
|
||||
UIButton *button = [[UIButton alloc] init];
|
||||
NSMutableAttributedString *attributedTitle = [[NSMutableAttributedString alloc] initWithString:title];
|
||||
[attributedTitle setAttributes:buttonTextAttributes range:NSMakeRange(0, [attributedTitle length])];
|
||||
[button setAttributedTitle:attributedTitle forState:UIControlStateNormal];
|
||||
|
||||
NSDictionary *disabledAttributes = @{
|
||||
NSFontAttributeName : [UIFont ows_regularFontWithSize:15.0f],
|
||||
NSForegroundColorAttributeName : [UIColor ows_darkGrayColor]
|
||||
};
|
||||
NSMutableAttributedString *attributedTitleDisabled = [[NSMutableAttributedString alloc] initWithString:title];
|
||||
[attributedTitleDisabled setAttributes:disabledAttributes range:NSMakeRange(0, [attributedTitle length])];
|
||||
[button setAttributedTitle:attributedTitleDisabled forState:UIControlStateDisabled];
|
||||
|
||||
[button.titleLabel setTextAlignment:NSTextAlignmentCenter];
|
||||
return button;
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -141,13 +141,15 @@ typedef enum : NSUInteger {
|
|||
}
|
||||
|
||||
|
||||
-(void) hideInputIfNeeded {
|
||||
- (void)hideInputIfNeeded {
|
||||
if([_thread isKindOfClass:[TSGroupThread class]] && ![((TSGroupThread*)_thread).groupModel.groupMemberIds containsObject:[SignalKeyingStorage.localNumber toE164]]) {
|
||||
[self inputToolbar].hidden= YES; // user has requested they leave the group. further sends disallowed
|
||||
self.navigationItem.rightBarButtonItem = nil; // further group action disallowed
|
||||
}
|
||||
else if(![self isTextSecureReachable] ){
|
||||
[self inputToolbar].hidden= YES; // only RedPhone
|
||||
} else {
|
||||
[self loadDraftInCompose];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,6 +164,7 @@ typedef enum : NSUInteger {
|
|||
_toggleContactPhoneDisplay.numberOfTapsRequired = 1;
|
||||
|
||||
_messageButton = [UIButton ows_blueButtonWithTitle:NSLocalizedString(@"SEND_BUTTON_TITLE", @"")];
|
||||
_messageButton.enabled = FALSE;
|
||||
|
||||
_attachButton = [[UIButton alloc] init];
|
||||
[_attachButton setFrame:CGRectMake(0, 0, JSQ_TOOLBAR_ICON_WIDTH+JSQ_IMAGE_INSET*2, JSQ_TOOLBAR_ICON_HEIGHT+JSQ_IMAGE_INSET*2)];
|
||||
|
@ -198,9 +201,9 @@ typedef enum : NSUInteger {
|
|||
self.navigationController.interactivePopGestureRecognizer.delegate = self; // Swipe back to inbox fix. See http://stackoverflow.com/questions/19054625/changing-back-button-in-ios-7-disables-swipe-to-navigate-back
|
||||
}
|
||||
|
||||
-(void) initializeTextView {
|
||||
- (void)initializeTextView {
|
||||
[self.inputToolbar.contentView.textView setFont:[UIFont ows_regularFontWithSize:17.f]];
|
||||
self.inputToolbar.contentView.leftBarButtonItem = _attachButton;
|
||||
self.inputToolbar.contentView.leftBarButtonItem = _attachButton;
|
||||
|
||||
self.inputToolbar.contentView.rightBarButtonItem = _messageButton;
|
||||
}
|
||||
|
@ -263,6 +266,7 @@ typedef enum : NSUInteger {
|
|||
|
||||
[self cancelReadTimer];
|
||||
[self removeTitleLabelGestureRecognizer];
|
||||
[self saveDraft];
|
||||
}
|
||||
|
||||
- (void)viewDidDisappear:(BOOL)animated{
|
||||
|
@ -527,7 +531,6 @@ typedef enum : NSUInteger {
|
|||
|
||||
- (void)textViewDidChange:(UITextView *)textView {
|
||||
if([textView.text length]>0) {
|
||||
self.inputToolbar.contentView.rightBarButtonItem = _messageButton;
|
||||
self.inputToolbar.contentView.rightBarButtonItem.enabled = YES;
|
||||
}
|
||||
else {
|
||||
|
@ -1186,7 +1189,6 @@ typedef enum : NSUInteger {
|
|||
|
||||
[self dismissViewControllerAnimated:YES completion:^{
|
||||
[[TSMessagesManager sharedManager] sendAttachment:attachmentData contentType:attachmentType inMessage:message thread:self.thread];
|
||||
[self finishSendingMessage];
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -1310,7 +1312,6 @@ typedef enum : NSUInteger {
|
|||
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
TSGroupThread* gThread = (TSGroupThread*)self.thread;
|
||||
self.thread = [TSGroupThread threadWithGroupModel:gThread.groupModel transaction:transaction];
|
||||
[self initializeToolbars];
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -1560,7 +1561,6 @@ typedef enum : NSUInteger {
|
|||
[self performSegueWithIdentifier:kUpdateGroupSegueIdentifier sender:self];
|
||||
}
|
||||
|
||||
|
||||
- (void)leaveGroup {
|
||||
[self.navController hideDropDown:self];
|
||||
|
||||
|
@ -1615,6 +1615,30 @@ typedef enum : NSUInteger {
|
|||
[self.inputToolbar.contentView.textView resignFirstResponder];
|
||||
}
|
||||
|
||||
#pragma mark Drafts
|
||||
|
||||
- (void)loadDraftInCompose
|
||||
{
|
||||
__block NSString *placeholder;
|
||||
[self.editingDatabaseConnection asyncReadWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
placeholder = [_thread currentDraftWithTransaction:transaction];
|
||||
} completionBlock:^{
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[self.inputToolbar.contentView.textView setText:placeholder];
|
||||
[self textViewDidChange:self.inputToolbar.contentView.textView];
|
||||
});
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)saveDraft
|
||||
{
|
||||
if (self.inputToolbar.hidden == NO) {
|
||||
[self.editingDatabaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||
[_thread setDraft:self.inputToolbar.contentView.textView.text transaction:transaction];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)dealloc{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue