diff --git a/src/ConversationVC.mm b/src/ConversationVC.mm
index 7ae6cf501a74d73d38b465328c6aa11fbaa9e150..127a16a75f53e31e70ae65b4b8fb5be13dd03638 100644
--- a/src/ConversationVC.mm
+++ b/src/ConversationVC.mm
@@ -196,13 +196,7 @@ NSInteger const SEND_PANEL_MAX_HEIGHT = 120;
         return;
 
     // Setup UI elements according to new conversation
-    NSLog(@"account info, %@", conv->accountId.toNSString());
-    NSLog(@"conv info, %@", conv->uid.toNSString());
-    NSLog(@"paricipant info, %@", conv->participants[0].toNSString());
     NSString* bestName = bestNameForConversation(*conv, *convModel_);
-    NSLog(@"account info, %@", conv->accountId.toNSString());
-    NSLog(@"conv info, %@", conv->uid.toNSString());
-    NSLog(@"paricipant info, %@", conv->participants[0].toNSString());
     NSString* bestId = bestIDForConversation(*conv, *convModel_);
     [conversationTitle setStringValue: bestName];
     [conversationID setStringValue: bestId];
@@ -218,6 +212,9 @@ NSInteger const SEND_PANEL_MAX_HEIGHT = 120;
     } catch (std::out_of_range& e) {
         NSLog(@"contact out of range");
     }
+    if (!conv->allMessagesLoaded) {
+        convModel_->loadConversationMessages(convUid_, 0);
+    }
 }
 
 - (void) initFrame
diff --git a/src/MessagesVC.mm b/src/MessagesVC.mm
index 6a8642e228795188fef80e6ec70d9cff4cb43003..5d4cc0192377ec721aad428ed554077daaf08e4a 100644
--- a/src/MessagesVC.mm
+++ b/src/MessagesVC.mm
@@ -64,6 +64,7 @@
     QString convUid_;
     lrc::api::ConversationModel* convModel_;
     const lrc::api::conversation::Info* cachedConv_;
+    std::vector<std::pair<QString, lrc::api::interaction::Info >> messages;
     lrc::api::AVModel* avModel;
     QMetaObject::Connection newInteractionSignal_;
 
@@ -75,6 +76,7 @@
     QMetaObject::Connection interactionRemovedSignal_;
     QMetaObject::Connection peerComposingMsgSignal_;
     QMetaObject::Connection lastDisplayedChanged_;
+    QMetaObject::Connection newMessages_;
     NSString* previewImage;
     NSMutableDictionary *pendingMessagesToSend;
     RecordFileVC* recordingController;
@@ -181,6 +183,7 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
     cachedConv_ = nil;
     convUid_ = "";
     convModel_ = nil;
+    messages = {};
 
     QObject::disconnect(modelSortedSignal_);
     QObject::disconnect(filterChangedSignal_);
@@ -188,6 +191,7 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
     QObject::disconnect(newInteractionSignal_);
     QObject::disconnect(peerComposingMsgSignal_);
     QObject::disconnect(lastDisplayedChanged_);
+    QObject::disconnect(newMessages_);
     [self closeRecordingView];
 }
 
@@ -219,31 +223,24 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
 }
 
 -(void) reloadConversationForMessage:(const QString&) uid updateSize:(BOOL) update {
-    auto* conv = [self getCurrentConversation];
-    if (conv == nil)
-        return;
-    auto it = conv->interactions.find(uid);
-    if (it == conv->interactions.end()) {
+    auto index = [self indexOfIntercation: uid];
+    if (index < 0) {
         return;
     }
-    auto itIndex = distance(conv->interactions.begin(),it);
-    if (itIndex >= ([conversationView numberOfRows] - 1) || itIndex >= conv->interactions.size()) {
-        return;
-    }
-    NSRange rangeToUpdate = NSMakeRange(itIndex, 2);
+    auto it = messages.at(index);
+    NSRange rangeToUpdate = NSMakeRange(index, 2);
     NSIndexSet* indexSet = [NSIndexSet indexSetWithIndexesInRange:rangeToUpdate];
     //reload previous message to update bubbleview
-    if (itIndex > 0) {
+    if (index > 0) {
         auto previousIt = it;
-        previousIt--;
-        auto previousInteraction = previousIt->second;
+        auto previousInteraction = messages.at(index-1).second;
         if (previousInteraction.type == lrc::api::interaction::Type::TEXT) {
-            NSRange range = NSMakeRange(itIndex - 1, 3);
+            NSRange range = NSMakeRange(index - 1, 3);
             indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
         }
     }
     if (update) {
-        NSRange insertRange = NSMakeRange(itIndex, 1);
+        NSRange insertRange = NSMakeRange(index, 1);
         NSIndexSet* insertRangeSet = [NSIndexSet indexSetWithIndexesInRange:insertRange];
         [conversationView removeRowsAtIndexes:insertRangeSet withAnimation:(NSTableViewAnimationEffectNone)];
         [conversationView insertRowsAtIndexes:insertRangeSet withAnimation:(NSTableViewAnimationEffectNone)];
@@ -263,6 +260,7 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
     convModel_ = model;
     peerComposingMessage = false;
     composingMessage = false;
+    [self reloadMessages];
 
     // Signal triggered when messages are received or their status updated
     QObject::disconnect(newInteractionSignal_);
@@ -270,6 +268,7 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
     QObject::disconnect(peerComposingMsgSignal_);
     QObject::disconnect(lastDisplayedChanged_);
     QObject::disconnect(interactionRemovedSignal_);
+    QObject::disconnect(newMessages_);
     lastDisplayedChanged_ =
     QObject::connect(convModel_,
                      &lrc::api::ConversationModel::displayedInteractionChanged,
@@ -283,6 +282,27 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
         [self reloadConversationForMessage:previousUid updateSize: NO];
     });
 
+    newMessages_ =
+    QObject::connect(convModel_,
+                     &lrc::api::ConversationModel::newMessagesAvailable,
+                     [self](const QString &accountId,
+                            const QString &conversationId) {
+        if (conversationId != convUid_)
+            return;
+        cachedConv_ = nil;
+        [self reloadMessages];
+        conversationView.alphaValue = 0.0;
+        [conversationView reloadData];
+        [conversationView scrollToEndOfDocument:nil];
+        CABasicAnimation *fadeIn = [CABasicAnimation animationWithKeyPath:@"opacity"];
+        fadeIn.fromValue = [NSNumber numberWithFloat:0.0];
+        fadeIn.toValue = [NSNumber numberWithFloat:1.0];
+        fadeIn.duration = 0.4f;
+
+        [conversationView.layer addAnimation:fadeIn forKey:fadeIn.keyPath];
+        conversationView.alphaValue = 1;
+    });
+
     peerComposingMsgSignal_ = QObject::connect(convModel_,
                                                &lrc::api::ConversationModel::composingStatusChanged,
                                                [self](const QString &uid,
@@ -322,10 +342,12 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
         }
     });
     newInteractionSignal_ = QObject::connect(convModel_, &lrc::api::ConversationModel::newInteraction,
-                                             [self](const QString& uid, QString& interactionId, const lrc::api::interaction::Info& interaction){
-        if (uid != convUid_)
+                                             [self](const QString& uid, QString& interactionId, const lrc::api::interaction::Info& interaction) {
+        bool transferForOtherDevice = interaction.type == lrc::api::interaction::Type::DATA_TRANSFER && interaction.body.isEmpty() && lrc::api::interaction::isOutgoing(interaction);
+        if (uid != convUid_ || interaction.type ==  lrc::api::interaction::Type::MERGE || transferForOtherDevice)
             return;
         cachedConv_ = nil;
+        messages.push_back(std::make_pair(interactionId, interaction));
         peerComposingMessage = false;
         [conversationView noteNumberOfRowsChanged];
         [self reloadConversationForMessage:interactionId updateSize: YES];
@@ -335,11 +357,12 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
                                                        [self](const QString& uid, const QString&  interactionId, const lrc::api::interaction::Info& interaction){
         if (uid != convUid_)
             return;
-        cachedConv_ = nil;
-        bool isOutgoing = lrc::api::interaction::isOutgoing(interaction);
-        if (interaction.type == lrc::api::interaction::Type::TEXT && isOutgoing) {
-            convModel_->refreshFilter();
+        auto index = [self indexOfIntercation: interactionId];
+        if (index < 0) {
+            return;
         }
+        cachedConv_ = nil;
+        messages.at(index).second = interaction;
         [self reloadConversationForMessage:interactionId updateSize: interaction.type == lrc::api::interaction::Type::DATA_TRANSFER];
         [self scrollToBottom];
     });
@@ -414,6 +437,26 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
     messageView.placeholderAttributedString = attributedPlaceholder;
 }
 
+-(void)reloadMessages {
+    auto* conv = [self getCurrentConversation];
+    messages = {};
+    for (auto& interaction : conv->interactions) {
+        bool transferForOtherDevice = interaction.second.type == lrc::api::interaction::Type::DATA_TRANSFER && interaction.second.body.isEmpty() && lrc::api::interaction::isOutgoing(interaction.second);
+        if (interaction.second.type != lrc::api::interaction::Type::MERGE && !transferForOtherDevice) {
+            messages.push_back(std::make_pair(interaction.first, interaction.second));
+        }
+    }
+}
+
+-(int)indexOfIntercation:(const QString&)uid {
+    for (int i = 0; i < messages.size(); i++) {
+        if (messages.at(i).first == uid) {
+            return i;
+        }
+    }
+    return -1;
+}
+
 #pragma mark - configure cells
 
 -(NSTableCellView*) makeGenericInteractionViewForTableView:(NSTableView*)tableView withText:(NSString*)text andTime:(NSString*) time
@@ -695,10 +738,10 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
         return nil;
 
     IMTableCellView* result;
-    auto it = conv->interactions.begin();
+    auto it = messages.begin();
     auto size = [conversationView numberOfRows] - 1;
 
-    if (row > size || row > conv->interactions.size()) {
+    if (row > size || row > messages.size()) {
         return [[NSView alloc] init];
     }
 
@@ -726,7 +769,7 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
 
     std::advance(it, row);
 
-    if (it == conv->interactions.end()) {
+    if (it == messages.end()) {
         return [[NSView alloc] init];
     }
 
@@ -841,30 +884,24 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
     try {
         double someWidth = tableView.frame.size.width * 0.7;
 
-        auto* conv = [self getCurrentConversation];
-
-        if (conv == nil)
-            return HEIGHT_DEFAULT;
-
         auto size = [conversationView numberOfRows] - 1;
 
-        if (row > size || row > conv->interactions.size()) {
+        if (row > size || row > messages.size()) {
             return HEIGHT_DEFAULT;
         }
         if (row == size) {
             return peerComposingMessage ? HEIGHT_FOR_COMPOSING_INDICATOR : DEFAULT_ROW_HEIGHT;
         }
 
-        auto it = conv->interactions.begin();
+        auto it = messages.begin();
 
         std::advance(it, row);
 
-        if (it == conv->interactions.end()) {
+        if (it == messages.end()) {
             return HEIGHT_DEFAULT;
         }
 
         auto interaction = it->second;
-
         MessageSequencing sequence = [self computeSequencingFor:row];
 
         bool shouldDisplayTime = (sequence == FIRST_WITH_TIME || sequence == SINGLE_WITH_TIME) ? YES : NO;
@@ -922,7 +959,7 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
 
 -(NSString *) getDataTransferPath:(const QString&)interactionId {
     lrc::api::datatransfer::Info info = {};
-    convModel_->getTransferInfo(interactionId, info);
+    convModel_->getTransferInfo(convUid_, interactionId, info);
     double convertData = static_cast<double>(info.totalSize);
     return info.path.toNSString();
 }
@@ -950,15 +987,12 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
 
 -(MessageSequencing) computeSequencingFor:(NSInteger) row {
     try {
-        auto* conv = [self getCurrentConversation];
-        if (row >= conversationView.numberOfRows - 1 || row >= conv->interactions.size()) {
+        if (row >= conversationView.numberOfRows - 1 || row >= messages.size()) {
             return SINGLE_WITHOUT_TIME;
         }
-        if (conv == nil)
-            return SINGLE_WITHOUT_TIME;
-        auto it = conv->interactions.begin();
+        auto it = messages.begin();
         std::advance(it, row);
-        if (it == conv->interactions.end()) {
+        if (it == messages.end()) {
             return SINGLE_WITHOUT_TIME;
         }
         auto interaction = it->second;
@@ -967,12 +1001,12 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
         }
         // first message in comversation
         if (row == 0) {
-            if (it == conv->interactions.end() || conv->interactions.size() < 2) {
+            if (it == messages.end() || messages.size() < 2) {
                 return SINGLE_WITH_TIME;
             }
             auto nextIt = it;
             nextIt++;
-            if (nextIt == conv->interactions.end()) {
+            if (nextIt == messages.end()) {
                 return SINGLE_WITH_TIME;
             }
             auto nextInteraction = nextIt->second;
@@ -982,12 +1016,12 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
             return FIRST_WITH_TIME;
         }
         // last message in comversation
-        if (row == conv->interactions.size() - 1) {
-            if(it == conv->interactions.begin()) {
+        if (row == messages.size() - 1) {
+            if(it == messages.begin()) {
                 return SINGLE_WITH_TIME;
             }
             auto previousIt = it;
-            previousIt--;
+            std::advance(previousIt, -1);
             auto previousInteraction = previousIt->second;
             bool timeChanged = [self sequenceTimeChangedFrom:interaction to:previousInteraction];
             bool authorChanged = [self sequenceAuthorChangedFrom:interaction to:previousInteraction];
@@ -1000,16 +1034,17 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
             return SINGLE_WITH_TIME;
         }
         // single message in comversation
-        if(it == conv->interactions.begin() || it == conv->interactions.end()) {
+        if(it == messages.begin() || it == messages.end()) {
             return SINGLE_WITH_TIME;
         }
         // message in the middle of conversation
         auto previousIt = it;
-        previousIt--;
+        std::advance(previousIt, -1);
+       // previousIt--;
         auto previousInteraction = previousIt->second;
         auto nextIt = it;
         nextIt++;
-        if (nextIt == conv->interactions.end()) {
+        if (nextIt == messages.end()) {
             return SINGLE_WITHOUT_TIME;
         }
         auto nextInteraction = nextIt->second;
@@ -1129,8 +1164,9 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
     auto* conv = [self getCurrentConversation];
 
     // return conversation +1 view for composing indicator
-    if (conv)
-        return conv->interactions.size() + 1;
+    if (conv) {
+        return messages.size() + 1;
+    }
     else
         return 0;
 }
@@ -1171,16 +1207,15 @@ typedef NS_ENUM(NSInteger, MessageSequencing) {
 
 - (void)acceptIncomingFile:(id)sender {
     auto interId = [(IMTableCellView*)[[[[[[sender superview] superview] superview] superview] superview] superview] interaction];
-    auto& inter = [self getCurrentConversation]->interactions.find(interId)->second;
     if (convModel_ && !convUid_.isEmpty()) {
         convModel_->acceptTransfer(convUid_, interId);
     }
 }
 
 - (void)declineIncomingFile:(id)sender {
-    auto inter = [(IMTableCellView*)[[[[[[sender superview] superview] superview] superview] superview] superview] interaction];
+    auto interId = [(IMTableCellView*)[[[[[[sender superview] superview] superview] superview] superview] superview] interaction];
     if (convModel_ && !convUid_.isEmpty()) {
-        convModel_->cancelTransfer(convUid_, inter);
+        convModel_->cancelTransfer(convUid_, interId);
     }
 }
 
diff --git a/src/SmartViewVC.mm b/src/SmartViewVC.mm
index f3f510d1d11ea803ab48c6780a86eb42fa7848d8..32820daf43a82c5e498a2110d79c392f4427d831 100755
--- a/src/SmartViewVC.mm
+++ b/src/SmartViewVC.mm
@@ -183,7 +183,6 @@ NSInteger const REQUEST_SEG         = 1;
     [searchResultsView layoutSubtreeIfNeeded];
 }
 
-
 -(void) reloadData
 {
     [contactsHeader setHidden: convModel_->allFilteredConversations().get().empty() || searchField.stringValue.length == 0];
@@ -276,6 +275,7 @@ NSInteger const REQUEST_SEG         = 1;
     QObject::disconnect(newInteractionConnection_);
     QObject::disconnect(searchStatusChangedConnection_);
     QObject::disconnect(searchResultUpdated_);
+    convModel_->setFilter(currentFilterType);
     [self reloadData];
     [self reloadSearchResults];
 
diff --git a/ui/Base.lproj/Conversation.xib b/ui/Base.lproj/Conversation.xib
index 5ebe2a2fa3286b8b48a6e0d47badbfbe58f171fc..794d1037caeafabcfbba4f923c17997f0411fa9c 100644
--- a/ui/Base.lproj/Conversation.xib
+++ b/ui/Base.lproj/Conversation.xib
@@ -10,6 +10,8 @@
                 <outlet property="addContactButton" destination="pGK-hO-X1Y" id="YeP-Gd-x6e"/>
                 <outlet property="conversationID" destination="SQT-Vf-Lhr" id="eab-vD-7X7"/>
                 <outlet property="conversationTitle" destination="ucx-6g-eJw" id="40T-pM-nix"/>
+                <outlet property="loadingindicator" destination="jf4-9g-QVb" id="pGV-oY-KTG"/>
+                <outlet property="loadingindicatorContainer" destination="a2B-6B-Ge1" id="msM-JI-qUj"/>
                 <outlet property="messagesViewVC" destination="iH6-17-JsM" id="uxH-Ra-lSr"/>
                 <outlet property="pluginButton" destination="FvO-Yj-ry0" id="35Y-R2-Gwa"/>
                 <outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
@@ -947,8 +949,44 @@
                         <real value="3.4028234663852886e+38"/>
                     </customSpacing>
                 </stackView>
-                <customView translatesAutoresizingMaskIntoConstraints="NO" id="u1v-eG-gBV" customClass="DraggingDestinationView">
-                    <rect key="frame" x="0.0" y="0.0" width="838" height="666"/>
+                <customView hidden="YES" translatesAutoresizingMaskIntoConstraints="NO" id="a2B-6B-Ge1">
+                    <rect key="frame" x="299" y="251" width="200" height="80"/>
+                    <subviews>
+                        <stackView distribution="fill" orientation="vertical" alignment="centerX" spacing="10" horizontalStackHuggingPriority="249.99998474121094" verticalStackHuggingPriority="249.99998474121094" detachesHiddenViews="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ux8-7c-iqB">
+                            <rect key="frame" x="35" y="12" width="130" height="56"/>
+                            <subviews>
+                                <progressIndicator wantsLayer="YES" maxValue="100" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="jf4-9g-QVb">
+                                    <rect key="frame" x="50" y="26" width="30" height="30"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="30" id="FtR-se-7Fd"/>
+                                        <constraint firstAttribute="height" constant="30" id="cWd-oz-BGI"/>
+                                    </constraints>
+                                </progressIndicator>
+                                <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="3HL-Cv-WFO">
+                                    <rect key="frame" x="-2" y="0.0" width="134" height="16"/>
+                                    <textFieldCell key="cell" lineBreakMode="clipping" title="Loading conversation" id="mfD-q3-nnf">
+                                        <font key="font" usesAppearanceFont="YES"/>
+                                        <color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
+                                        <color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
+                                    </textFieldCell>
+                                </textField>
+                            </subviews>
+                            <visibilityPriorities>
+                                <integer value="1000"/>
+                                <integer value="1000"/>
+                            </visibilityPriorities>
+                            <customSpacing>
+                                <real value="3.4028234663852886e+38"/>
+                                <real value="3.4028234663852886e+38"/>
+                            </customSpacing>
+                        </stackView>
+                    </subviews>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="80" id="UyJ-03-RLP"/>
+                        <constraint firstItem="ux8-7c-iqB" firstAttribute="centerX" secondItem="a2B-6B-Ge1" secondAttribute="centerX" id="fIA-5F-V8l"/>
+                        <constraint firstItem="ux8-7c-iqB" firstAttribute="centerY" secondItem="a2B-6B-Ge1" secondAttribute="centerY" id="o1A-cu-d8A"/>
+                        <constraint firstAttribute="width" constant="200" id="yiD-Tf-FpX"/>
+                    </constraints>
                 </customView>
             </subviews>
             <constraints>