Commit f631742b authored by Kateryna Kostiuk's avatar Kateryna Kostiuk Committed by Andreas Traczyk

call: implement leave message view

Change-Id: Ie4ab6134d39907d108e6a5bf39a863cb56ede684
Reviewed-by: Andreas Traczyk's avatarAndreas Traczyk <andreas.traczyk@savoirfairelinux.com>
parent f35cf30c
...@@ -167,6 +167,8 @@ SET(ringclient_CONTROLLERS ...@@ -167,6 +167,8 @@ SET(ringclient_CONTROLLERS
src/AddSIPAccountVC.h src/AddSIPAccountVC.h
src/AccountSettingsVC.mm src/AccountSettingsVC.mm
src/AccountSettingsVC.h src/AccountSettingsVC.h
src/LeaveMessageVC.mm
src/LeaveMessageVC.h
) )
SET(ringclient_BACKENDS SET(ringclient_BACKENDS
...@@ -261,6 +263,7 @@ SET(ringclient_XIBS ...@@ -261,6 +263,7 @@ SET(ringclient_XIBS
MessageCells MessageCells
AddSIPAccountVC AddSIPAccountVC
AccountSettings AccountSettings
LeaveMessageVC
) )
# Icons # Icons
...@@ -269,6 +272,10 @@ SET(myApp_ICON ${CMAKE_CURRENT_SOURCE_DIR}/data/appicon.icns) ...@@ -269,6 +272,10 @@ SET(myApp_ICON ${CMAKE_CURRENT_SOURCE_DIR}/data/appicon.icns)
SET_SOURCE_FILES_PROPERTIES(${myApp_ICON} PROPERTIES SET_SOURCE_FILES_PROPERTIES(${myApp_ICON} PROPERTIES
MACOSX_PACKAGE_LOCATION Resources) MACOSX_PACKAGE_LOCATION Resources)
SET(ring_ICONS SET(ring_ICONS
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_audio_file.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_exit.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_stoprecord.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_action_audio.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_action_audio.png ${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_action_audio.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_folder.png ${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_folder.png
${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_action_block.png ${CMAKE_CURRENT_SOURCE_DIR}/data/dark/ic_action_block.png
......
...@@ -319,7 +319,7 @@ static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNet ...@@ -319,7 +319,7 @@ static void ReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNet
- (void) showMainWindow - (void) showMainWindow
{ {
if(self.ringWindowController == nil) { if(self.ringWindowController == nil) {
self.ringWindowController = [[RingWindowController alloc] initWithWindowNibName:@"RingWindow" bundle: nil accountModel:&lrc->getAccountModel() dataTransferModel:&lrc->getDataTransferModel() behaviourController:&lrc->getBehaviorController()]; self.ringWindowController = [[RingWindowController alloc] initWithWindowNibName:@"RingWindow" bundle: nil accountModel:&lrc->getAccountModel() dataTransferModel:&lrc->getDataTransferModel() behaviourController:&lrc->getBehaviorController() avModel: &lrc->getAVModel()];
} }
[[NSApplication sharedApplication] removeWindowsItem:self.wizard.window]; [[NSApplication sharedApplication] removeWindowsItem:self.wizard.window];
[self.ringWindowController.window makeKeyAndOrderFront:self]; [self.ringWindowController.window makeKeyAndOrderFront:self];
......
...@@ -18,12 +18,19 @@ ...@@ -18,12 +18,19 @@
*/ */
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <api/conversation.h> #import <string>
#import <api/conversationmodel.h>
namespace lrc {
namespace api {
class AVModel;
class ConversationModel;
}
}
@class RingWindowController; @class RingWindowController;
@class LeaveMessageVC;
@protocol LeaveMessageDelegate;
@interface ConversationVC : NSViewController @interface ConversationVC : NSViewController <LeaveMessageDelegate>
-(void) initFrame; -(void) initFrame;
-(void) showWithAnimation:(BOOL)animate; -(void) showWithAnimation:(BOOL)animate;
...@@ -31,6 +38,9 @@ ...@@ -31,6 +38,9 @@
- (void) setConversationUid:(const std::string)convUid model:(lrc::api::ConversationModel*)model; - (void) setConversationUid:(const std::string)convUid model:(lrc::api::ConversationModel*)model;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil delegate:(RingWindowController*) mainWindow; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil delegate:(RingWindowController*) mainWindow aVModel:(lrc::api::AVModel*) avModel;
- (void) presentLeaveMessageView;
-(NSViewController*) getMessagesView;
@end @end
...@@ -36,8 +36,12 @@ ...@@ -36,8 +36,12 @@
#import "utils.h" #import "utils.h"
#import "RingWindowController.h" #import "RingWindowController.h"
#import "NSString+Extensions.h" #import "NSString+Extensions.h"
#import "LeaveMessageVC.h"
#import <QuickLook/QuickLook.h>
#import <Quartz/Quartz.h>
#import "LeaveMessageVC.h"
@interface ConversationVC () { @interface ConversationVC () <QLPreviewPanelDataSource, QLPreviewPanelDelegate>{
__unsafe_unretained IBOutlet NSTextField* conversationTitle; __unsafe_unretained IBOutlet NSTextField* conversationTitle;
__unsafe_unretained IBOutlet NSTextField *conversationID; __unsafe_unretained IBOutlet NSTextField *conversationID;
...@@ -46,6 +50,7 @@ ...@@ -46,6 +50,7 @@
__unsafe_unretained IBOutlet NSButton* sentContactRequestButton; __unsafe_unretained IBOutlet NSButton* sentContactRequestButton;
IBOutlet MessagesVC* messagesViewVC; IBOutlet MessagesVC* messagesViewVC;
LeaveMessageVC* leaveMessageVC;
IBOutlet NSLayoutConstraint *titleCenteredConstraint; IBOutlet NSLayoutConstraint *titleCenteredConstraint;
IBOutlet NSLayoutConstraint* titleTopConstraint; IBOutlet NSLayoutConstraint* titleTopConstraint;
...@@ -55,6 +60,7 @@ ...@@ -55,6 +60,7 @@
lrc::api::ConversationModel* convModel_; lrc::api::ConversationModel* convModel_;
RingWindowController* delegate; RingWindowController* delegate;
NSMutableArray* leaveMessageConversations;
// All those connections are needed to invalidate cached conversation as pointer // All those connections are needed to invalidate cached conversation as pointer
// may not be referencing the same conversation anymore // may not be referencing the same conversation anymore
...@@ -69,15 +75,26 @@ NSInteger const SEND_PANEL_MAX_HEIGHT = 120; ...@@ -69,15 +75,26 @@ NSInteger const SEND_PANEL_MAX_HEIGHT = 120;
@implementation ConversationVC @implementation ConversationVC
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil delegate:(RingWindowController*) mainWindow - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil delegate:(RingWindowController*) mainWindow aVModel:(lrc::api::AVModel*) avModel
{ {
if (self = [self initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) if (self = [self initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{ {
delegate = mainWindow; delegate = mainWindow;
leaveMessageVC = [[LeaveMessageVC alloc] initWithNibName:@"LeaveMessageVC" bundle:nil];
[[leaveMessageVC view] setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[self.view addSubview:[leaveMessageVC view] positioned:NSWindowAbove relativeTo:nil];
[leaveMessageVC initFrame];
[leaveMessageVC setAVModel: avModel];
leaveMessageConversations = [[NSMutableArray alloc] init];
leaveMessageVC.delegate = self;
} }
return self; return self;
} }
-(NSViewController*) getMessagesView {
return messagesViewVC;
}
-(void) clearData { -(void) clearData {
cachedConv_ = nil; cachedConv_ = nil;
convUid_ = ""; convUid_ = "";
...@@ -120,6 +137,11 @@ NSInteger const SEND_PANEL_MAX_HEIGHT = 120; ...@@ -120,6 +137,11 @@ NSInteger const SEND_PANEL_MAX_HEIGHT = 120;
if (convUid_.empty() || convModel_ == nil) if (convUid_.empty() || convModel_ == nil)
return; return;
if([leaveMessageConversations containsObject:@(convUid_.c_str())]) {
[leaveMessageVC setConversationUID: convUid_ conversationModel: convModel_];
} else {
[leaveMessageVC hide];
}
// Signals tracking changes in conversation list, we need them as cached conversation can be invalid // Signals tracking changes in conversation list, we need them as cached conversation can be invalid
// after a reordering. // after a reordering.
...@@ -247,5 +269,13 @@ NSInteger const SEND_PANEL_MAX_HEIGHT = 120; ...@@ -247,5 +269,13 @@ NSInteger const SEND_PANEL_MAX_HEIGHT = 120;
[CATransaction commit]; [CATransaction commit];
} }
- (void) presentLeaveMessageView {
[leaveMessageVC setConversationUID: convUid_ conversationModel: convModel_];
[leaveMessageConversations addObject:@(convUid_.c_str())];
}
-(void) messageCompleted {
[leaveMessageConversations removeObject:@(convUid_.c_str())];
}
@end @end
/*
* Copyright (C) 2018 Savoir-faire Linux Inc.
* Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import <Cocoa/Cocoa.h>
#import <string>
namespace lrc {
namespace api {
class AVModel;
class ConversationModel;
}
}
@protocol LeaveMessageDelegate
-(void) messageCompleted;
@end
@interface LeaveMessageVC : NSViewController
@property (retain, nonatomic) id <LeaveMessageDelegate> delegate;
-(void)setConversationUID:(const std::string) convUid conversationModel:(lrc::api::ConversationModel*) convModel;
-(void) hide;
-(void) initFrame;
-(void) setAVModel: (const lrc::api::AVModel*) avmodel;
@end
/*
* Copyright (C) 2018 Savoir-faire Linux Inc.
* Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#import "LeaveMessageVC.h"
#import "views/NSColor+RingTheme.h"
#import "utils.h"
//lrc
#import <api/avmodel.h>
#import <api/conversationmodel.h>
#import <QuartzCore/QuartzCore.h>
#import "delegates/ImageManipulationDelegate.h"
//Qt
#import <QtMacExtras/qmacfunctions.h>
#import <QPixmap>
#import <globalinstances.h>
@interface LeaveMessageVC () {
__unsafe_unretained IBOutlet NSImageView* personPhoto;
__unsafe_unretained IBOutlet NSTextField* infoLabel;
__unsafe_unretained IBOutlet NSBox* timerBox;
__unsafe_unretained IBOutlet NSTextField* timerLabel;
__unsafe_unretained IBOutlet NSBox* sendBox;
__unsafe_unretained IBOutlet NSTextField* sendFilename;
__unsafe_unretained IBOutlet NSButton* recordButton;
}
@end
@implementation LeaveMessageVC
bool isRecording = false;
int recordingTime = 0;
NSTimer* refreshDurationTimer;
lrc::api::AVModel* avModel;
std::string fileName;
NSMutableDictionary *filesToSend;
std::string conversationUid;
lrc::api::ConversationModel* conversationModel;
- (void)loadView {
[super loadView];
[personPhoto setWantsLayer:YES];
personPhoto.layer.masksToBounds =true;
personPhoto.layer.cornerRadius = personPhoto.frame.size.width * 0.5;
filesToSend = [[NSMutableDictionary alloc] init];
}
-(void) setAVModel: (lrc::api::AVModel*) avmodel {
avModel = avmodel;
}
-(void) initFrame {
[self.view setFrame:self.view.superview.bounds];
[self.view setHidden:YES];
self.view.layer.position = self.view.frame.origin;
}
- (IBAction)cancel:(id)sender {
[self exit];
}
- (IBAction)recordMessage:(NSButton *)sender {
if (!isRecording) {
[self clearData];
std::string file_name = avModel->startLocalRecorder(true);
if (file_name.empty()) {
return;
}
filesToSend[@(conversationUid.c_str())] = @(file_name.c_str());
isRecording = true;
recordButton.image = [NSImage imageNamed:@"ic_stoprecord.png"];
[timerBox setHidden:NO];
if (refreshDurationTimer == nil)
refreshDurationTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(updateDurationLabel)
userInfo:nil
repeats:YES];
} else {
avModel->stopLocalRecorder([filesToSend[@(conversationUid.c_str())] UTF8String]);
isRecording = false;
recordButton.image = [NSImage imageNamed:@"ic_action_audio.png"];
[refreshDurationTimer invalidate];
refreshDurationTimer = nil;
[timerBox setHidden:YES];
[sendBox setHidden: NO];
[sendFilename setStringValue:[self timeFormatted: recordingTime]];
}
}
- (IBAction)sendMessage:(NSButton *)sender {
NSArray* pathURL = [filesToSend[@(conversationUid.c_str())] componentsSeparatedByString: @"/"];
if([pathURL count] < 1) {
return;
}
NSString* name = [pathURL objectAtIndex: [pathURL count] - 1];
conversationModel->sendFile(conversationUid, [filesToSend[@(conversationUid.c_str())] UTF8String], [name UTF8String]);
[filesToSend removeObjectForKey: @(conversationUid.c_str())];
[self exit];
}
- (void) exit {
[self clearData];
[self hide];
[self.delegate messageCompleted];
}
- (void)clearData {
recordButton.image = [NSImage imageNamed:@"ic_action_audio.png"];
recordingTime = 0;
[timerLabel setStringValue: [self timeFormatted: recordingTime]];
isRecording = false;
[timerBox setHidden:YES];
[sendBox setHidden: YES];
[refreshDurationTimer invalidate];
refreshDurationTimer = nil;
[sendFilename setStringValue:@""];
[filesToSend removeObjectForKey: @(conversationUid.c_str())];
}
- (void)viewWillHide {
recordButton.image = [NSImage imageNamed:@"ic_action_audio.png"];
if(filesToSend[@(conversationUid.c_str())]) {
[sendFilename setStringValue:[self timeFormatted: recordingTime]];
[sendBox setHidden: NO];
} else {
[sendFilename setStringValue:@""];
[sendBox setHidden: YES];
}
recordingTime = 0;
[timerLabel setStringValue: [self timeFormatted: recordingTime]];
isRecording = false;
[timerBox setHidden:YES];
[refreshDurationTimer invalidate];
refreshDurationTimer = nil;
}
-(void) hide {
if(self.view.frame.origin.x < 0) {
return;
}
[self viewWillHide];
[self.view setHidden:YES];
}
-(void) show {
if(self.view.frame.origin.x < 0) {
return;
}
[self.view setHidden:NO];
}
-(void)setConversationUID:(std::string) convUid conversationModel:(lrc::api::ConversationModel*) convModel {
conversationUid = convUid;
conversationModel = convModel;
[self updateView];
}
-(void) updateView {
auto it = getConversationFromUid(conversationUid, *conversationModel);
if (it != conversationModel->allFilteredConversations().end()) {
auto& imgManip = reinterpret_cast<Interfaces::ImageManipulationDelegate&>(GlobalInstances::pixmapManipulator());
QVariant photo = imgManip.conversationPhoto(*it, conversationModel->owner, QSize(120, 120), NO);
[personPhoto setImage:QtMac::toNSImage(qvariant_cast<QPixmap>(photo))];
NSString *name = bestNameForConversation(*it, *conversationModel);
[infoLabel setStringValue:name];
}
[self show];
}
-(void) updateDurationLabel
{
recordingTime++;
[timerLabel setStringValue: [self timeFormatted: recordingTime]];
}
- (NSString *)timeFormatted:(int)totalSeconds
{
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
return [NSString stringWithFormat:@"%02d:%02d",minutes, seconds];
}
@end
...@@ -22,6 +22,7 @@ namespace lrc { ...@@ -22,6 +22,7 @@ namespace lrc {
class DataTransferModel; class DataTransferModel;
class NewAccountModel; class NewAccountModel;
class BehaviorController; class BehaviorController;
class AVModel;
} }
} }
...@@ -30,9 +31,11 @@ namespace lrc { ...@@ -30,9 +31,11 @@ namespace lrc {
-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil dataTransferModel:(const lrc::api::DataTransferModel*) dataTransferModel; -(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil dataTransferModel:(const lrc::api::DataTransferModel*) dataTransferModel;
-(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountmodel:(const lrc::api::NewAccountModel*) accountModel; -(id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountmodel:(const lrc::api::NewAccountModel*) accountModel;
-(id) initWithWindowNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountModel:(const lrc::api::NewAccountModel*)accountModel dataTransferModel:(const lrc::api::DataTransferModel*)dataTransferModel behaviourController:(const lrc::api::BehaviorController*) behaviorController; -(id) initWithWindowNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountModel:(const lrc::api::NewAccountModel*)accountModel dataTransferModel:(const lrc::api::DataTransferModel*)dataTransferModel behaviourController:(const lrc::api::BehaviorController*) behaviorController;
-(id) initWithWindowNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil accountModel:(const lrc::api::NewAccountModel*)accountModel dataTransferModel:(const lrc::api::DataTransferModel*)dataTransferModel behaviourController:(const lrc::api::BehaviorController*) behaviorController avModel: (const lrc::api::AVModel*)avModel;
@property lrc::api::DataTransferModel* dataTransferModel; @property lrc::api::DataTransferModel* dataTransferModel;
@property lrc::api::NewAccountModel* accountModel; @property lrc::api::NewAccountModel* accountModel;
@property lrc::api::BehaviorController* behaviorController; @property lrc::api::BehaviorController* behaviorController;
@property lrc::api::AVModel* avModel;
@end @end
...@@ -50,7 +50,6 @@ ...@@ -50,7 +50,6 @@
std::string convUid_; std::string convUid_;
lrc::api::ConversationModel* convModel_; lrc::api::ConversationModel* convModel_;
const lrc::api::conversation::Info* cachedConv_; const lrc::api::conversation::Info* cachedConv_;
QMetaObject::Connection newInteractionSignal_; QMetaObject::Connection newInteractionSignal_;
// Both are needed to invalidate cached conversation as pointer // Both are needed to invalidate cached conversation as pointer
...@@ -790,6 +789,24 @@ typedef NS_ENUM(NSInteger, MessageSequencing) { ...@@ -790,6 +789,24 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
return [dateFormatter stringFromDate:msgTime]; return [dateFormatter stringFromDate:msgTime];
} }
- (void) updateSendMessageHeight {
NSAttributedString *msgAttString = messageField.attributedStringValue;
NSRect frame = NSMakeRect(0, 0, messageField.frame.size.width, msgAttString.size.height);
NSTextView *tv = [[NSTextView alloc] initWithFrame:frame];
[[tv textStorage] setAttributedString:msgAttString];
[tv sizeToFit];
CGFloat height = tv.frame.size.height + MEESAGE_MARGIN * 2;
CGFloat newHeight = MIN(SEND_PANEL_MAX_HEIGHT, MAX(SEND_PANEL_DEFAULT_HEIGHT, height));
if(messagesBottomMargin.constant == newHeight) {
return;
}
messagesBottomMargin.constant = newHeight;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.05 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self scrollToBottom];
sendPanelHeight.constant = newHeight;
});
}
#pragma mark - NSTableViewDataSource #pragma mark - NSTableViewDataSource
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
...@@ -877,39 +894,12 @@ typedef NS_ENUM(NSInteger, MessageSequencing) { ...@@ -877,39 +894,12 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
if ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]) { if ([QLPreviewPanel sharedPreviewPanelExists] && [[QLPreviewPanel sharedPreviewPanel] isVisible]) {
[[QLPreviewPanel sharedPreviewPanel] orderOut:nil]; [[QLPreviewPanel sharedPreviewPanel] orderOut:nil];
} else { } else {
[[QLPreviewPanel sharedPreviewPanel] updateController]; dispatch_async(dispatch_get_main_queue(), ^{
[QLPreviewPanel sharedPreviewPanel].dataSource = self; [[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:self];
[[QLPreviewPanel sharedPreviewPanel] setAnimationBehavior:NSWindowAnimationBehaviorDocumentWindow]; });
[[QLPreviewPanel sharedPreviewPanel] makeKeyAndOrderFront:nil];
} }
} }
- (NSInteger)numberOfPreviewItemsInPreviewPanel:(QLPreviewPanel *)panel {
return 1;
}
- (id <QLPreviewItem>)previewPanel:(QLPreviewPanel *)panel previewItemAtIndex:(NSInteger)index {
return [NSURL fileURLWithPath:previewImage];
}
- (void) updateSendMessageHeight {
NSAttributedString *msgAttString = messageField.attributedStringValue;
NSRect frame = NSMakeRect(0, 0, messageField.frame.size.width, msgAttString.size.height);
NSTextView *tv = [[NSTextView alloc] initWithFrame:frame];
[[tv textStorage] setAttributedString:msgAttString];
[tv sizeToFit];
CGFloat height = tv.frame.size.height + MEESAGE_MARGIN * 2;
CGFloat newHeight = MIN(SEND_PANEL_MAX_HEIGHT, MAX(SEND_PANEL_DEFAULT_HEIGHT, height));
if(messagesBottomMargin.constant == newHeight) {
return;
}
messagesBottomMargin.constant = newHeight;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.05 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[self scrollToBottom];
sendPanelHeight.constant = newHeight;
});
}
- (IBAction)sendMessage:(id)sender { - (IBAction)sendMessage:(id)sender {
NSString* text = self.message; NSString* text = self.message;
if (text && text.length > 0) { if (text && text.length > 0) {
...@@ -971,4 +961,28 @@ typedef NS_ENUM(NSInteger, MessageSequencing) { ...@@ -971,4 +961,28 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
[self updateSendMessageHeight]; [self updateSendMessageHeight];
} }
#pragma mark - QLPreviewPanelDataSource
-(void)beginPreviewPanelControl:(QLPreviewPanel *)panel
{
panel.dataSource = self;
}
- (void)endPreviewPanelControl:(QLPreviewPanel *)panel {
panel.dataSource = nil;