diff --git a/src/localtextrecordingcollection.cpp b/src/localtextrecordingcollection.cpp
index 91623caa01de09b763dbb3458531287407b43047..a9f46cd281240bdc442654099de1354507de6991 100644
--- a/src/localtextrecordingcollection.cpp
+++ b/src/localtextrecordingcollection.cpp
@@ -171,9 +171,57 @@ bool LocalTextRecordingCollection::isEnabled() const
 
 bool LocalTextRecordingCollection::load()
 {
-   //This collection is special as it use the history collection
-   //as its source, there is no loading
-   return true;
+    // load all text recordings so we can recover CMs that are not in the call history
+    QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/text/");
+    if (dir.exists()) {
+        // get .json files, sorted by time, latest first
+        QStringList filters;
+        filters << "*.json";
+        auto list = dir.entryInfoList(filters, QDir::Files | QDir::NoSymLinks | QDir::Readable, QDir::Time);
+
+        for (int i = 0; i < list.size(); ++i) {
+            QFileInfo fileInfo = list.at(i);
+
+            QString content;
+            QFile file(fileInfo.absoluteFilePath());
+            if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                content = QString::fromUtf8(file.readAll());
+            } else {
+                qWarning() << "Could not open text recording json file";
+            }
+
+            if (!content.isEmpty()) {
+                QJsonParseError err;
+                QJsonDocument loadDoc = QJsonDocument::fromJson(content.toUtf8(), &err);
+
+                if (err.error == QJsonParseError::ParseError::NoError) {
+                    Media::TextRecording* r = Media::TextRecording::fromJson({loadDoc.object()});
+
+                    editor<Media::Recording>()->addExisting(r);
+                    r->setCollection(this);
+
+                    // get CMs from recording
+                    for (ContactMethod *cm : r->peers()) {
+                        // since we load the recordings in order from newest to oldest, if there is
+                        // more than one found associated with a CM, we take the newest one
+                        if (!cm->d_ptr->m_pTextRecording) {
+                            cm->d_ptr->setTextRecording(r);
+                        } else {
+                            qWarning() << "CM already has text recording" << cm;
+                        }
+                    }
+                } else {
+                    qWarning() << "Error Decoding Text Message History Json" << err.errorString();
+                }
+            } else {
+                qWarning() << "Text recording file is empty";
+            }
+        }
+    }
+
+    // always return true, even if noting was loaded, since the collection can still be used to
+    // save files
+    return true;
 }
 
 bool LocalTextRecordingCollection::reload()
diff --git a/src/media/textrecording.cpp b/src/media/textrecording.cpp
index 5c99c66cd9cec703b8c7288998bb7fea837fb45c..215631de29b74b8c4ceefeffc6b9b71fff275441 100644
--- a/src/media/textrecording.cpp
+++ b/src/media/textrecording.cpp
@@ -208,6 +208,19 @@ void Media::TextRecording::setAllRead()
     }
 }
 
+QVector<ContactMethod*> Media::TextRecording::peers() const
+{
+    QVector<ContactMethod*> cms;
+
+    for (const Serializable::Peers* peers : d_ptr->m_lAssociatedPeers) {
+        for (const Serializable::Peer* peer : peers->peers) {
+            cms << peer->m_pContactMethod;
+        }
+    }
+
+    return cms;
+}
+
 /**
  * I (Emmanuel Lepage) is in the process of writing a better one for this that
  * can be upstreamed into Qt (there is interest in merging a generic QVariant
@@ -304,40 +317,61 @@ QHash<QByteArray,QByteArray> Media::TextRecordingPrivate::toJsons() const
 
 Media::TextRecording* Media::TextRecording::fromJson(const QList<QJsonObject>& items, const ContactMethod* cm)
 {
-   TextRecording* t = new TextRecording();
+    TextRecording* t = new TextRecording();
 
-   //Load the history data
-   for (const QJsonObject& obj : items) {
-      Serializable::Peers* p = SerializableEntityManager::fromJson(obj,cm);
-      t->d_ptr->m_lAssociatedPeers << p;
-   }
+    //Load the history data
+    for (const QJsonObject& obj : items) {
+        Serializable::Peers* p = SerializableEntityManager::fromJson(obj,cm);
+        t->d_ptr->m_lAssociatedPeers << p;
+    }
 
-   //Create the model
-   t->instantMessagingModel();
-
-   //Reconstruct the conversation
-   //TODO do it right, right now it flatten the graph
-   for (const Serializable::Peers* p : t->d_ptr->m_lAssociatedPeers) {
-      for (const Serializable::Group* g : p->groups) {
-         for (Serializable::Message* m : g->messages) {
-            ::TextMessageNode* n  = new ::TextMessageNode();
-            n->m_pMessage         = m                      ;
-            if (!n->m_pMessage->contactMethod) {
-               n->m_pMessage->contactMethod = const_cast<ContactMethod*>(cm); //TODO remove in 2016
-               n->m_pMessage->authorSha1 = cm->sha1();
-
-               if (p->peers.isEmpty())
-                  addPeer(const_cast<Serializable::Peers*>(p), cm);
+    //Create the model
+    t->instantMessagingModel();
+
+    //Reconstruct the conversation
+    //TODO do it right, right now it flatten the graph
+    for (const Serializable::Peers* p : t->d_ptr->m_lAssociatedPeers) {
+        // TODO: for now assume the convo is with only 1 CM at a time
+        auto peerCM = p->peers.at(0)->m_pContactMethod;
+
+        // get the latest timestamp to set last used
+        time_t lastUsed = 0;
+        for (const Serializable::Group* g : p->groups) {
+            for (Serializable::Message* m : g->messages) {
+                ::TextMessageNode* n  = new ::TextMessageNode();
+                n->m_pMessage         = m                      ;
+                if (!n->m_pMessage->contactMethod) {
+                    if (cm) {
+                        n->m_pMessage->contactMethod = const_cast<ContactMethod*>(cm); //TODO remove in 2016
+                        n->m_pMessage->authorSha1 = cm->sha1();
+
+                        if (p->peers.isEmpty())
+                        addPeer(const_cast<Serializable::Peers*>(p), cm);
+                    } else {
+                        if (p->m_hSha1.contains(n->m_pMessage->authorSha1)) {
+                            n->m_pMessage->contactMethod = p->m_hSha1[n->m_pMessage->authorSha1];
+                        } else {
+                            // message was outgoing and author sha1 was set to that of the sending account
+                            n->m_pMessage->contactMethod = peerCM;
+                            n->m_pMessage->authorSha1 = peerCM->sha1();
+                        }
+                    }
+                }
+                n->m_pContactMethod   = m->contactMethod;
+                t->d_ptr->m_pImModel->addRowBegin();
+                t->d_ptr->m_lNodes << n;
+                t->d_ptr->m_pImModel->addRowEnd();
+
+                if (lastUsed < n->m_pMessage->timestamp)
+                    lastUsed = n->m_pMessage->timestamp;
             }
-            n->m_pContactMethod   = m->contactMethod;
-            t->d_ptr->m_pImModel->addRowBegin();
-            t->d_ptr->m_lNodes << n;
-            t->d_ptr->m_pImModel->addRowEnd();
-         }
-      }
-   }
+        }
+
+        // update the timestamp of the CM
+        peerCM->setLastUsed(lastUsed);
+    }
 
-   return t;
+    return t;
 }
 
 void Media::TextRecordingPrivate::insertNewMessage(const QMap<QString,QString>& message, ContactMethod* cm, Media::Media::Direction direction)
diff --git a/src/media/textrecording.h b/src/media/textrecording.h
index fa4456f7bea2e209a265644393a88a3512cec75e..f0602e483608199ad9b237ad0bb58bcebe760edf 100644
--- a/src/media/textrecording.h
+++ b/src/media/textrecording.h
@@ -75,6 +75,7 @@ public:
    bool                isEmpty                  (                         ) const;
    bool                hasMimeType              ( const QString& mimeType ) const;
    QStringList         mimeTypes                (                         ) const;
+   QVector<ContactMethod*> peers                (                         ) const;
 
    //Helper
    void setAllRead();