diff --git a/src/chatview.cpp b/src/chatview.cpp
index b7ee941edd5724c8f1c8cfee557bb1d7dc52521d..3d873e1ff6c1b5d92741aee721d897557f99c882 100644
--- a/src/chatview.cpp
+++ b/src/chatview.cpp
@@ -60,6 +60,7 @@ struct _ChatViewPrivate
     AccountInfoPointer const * accountInfo_;
 
     QMetaObject::Connection new_interaction_connection;
+    QMetaObject::Connection interaction_removed;
     QMetaObject::Connection update_interaction_connection;
     QMetaObject::Connection update_add_to_conversations;
 
@@ -90,6 +91,7 @@ chat_view_dispose(GObject *object)
 
     QObject::disconnect(priv->new_interaction_connection);
     QObject::disconnect(priv->update_interaction_connection);
+    QObject::disconnect(priv->interaction_removed);
     QObject::disconnect(priv->update_add_to_conversations);
 
     /* Destroying the box will also destroy its children, and we wouldn't
@@ -269,6 +271,14 @@ webkit_chat_container_script_dialog(GtkWidget* webview, gchar *interaction, Chat
         }
     } else if (order.find("ADD_TO_CONVERSATIONS") == 0) {
         button_add_to_conversations_clicked(self);
+    } else if (order.find("DELETE_INTERACTION:") == 0) {
+        try {
+            auto interactionId = std::stoull(order.substr(std::string("DELETE_INTERACTION:").size()));
+            if (!priv->conversation_) return;
+            (*priv->accountInfo_)->conversationModel->clearInteractionFromConversation(priv->conversation_->uid, interactionId);
+        } catch (...) {
+            g_warning("delete interaction failed: can't find %s", order.substr(std::string("DELETE_INTERACTION:").size()).c_str());
+        }
     }
 }
 
@@ -341,6 +351,16 @@ update_interaction(ChatView* self, uint64_t interactionId, const lrc::api::inter
     );
 }
 
+static void
+remove_interaction(ChatView* self, uint64_t interactionId)
+{
+    ChatViewPrivate *priv = CHAT_VIEW_GET_PRIVATE(self);
+    webkit_chat_container_remove_interaction(
+        WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
+        interactionId
+    );
+}
+
 static void
 load_participants_images(ChatView *self)
 {
@@ -415,7 +435,7 @@ webkit_chat_container_ready(ChatView* self)
     &*(*priv->accountInfo_)->conversationModel, &lrc::api::ConversationModel::newInteraction,
     [self, priv](const std::string& uid, uint64_t interactionId, lrc::api::interaction::Info interaction) {
         if (!priv->conversation_) return;
-        if(uid == priv->conversation_->uid) {
+        if (uid == priv->conversation_->uid) {
             print_interaction_to_buffer(self, interactionId, interaction);
         }
     });
@@ -424,11 +444,20 @@ webkit_chat_container_ready(ChatView* self)
     &*(*priv->accountInfo_)->conversationModel, &lrc::api::ConversationModel::interactionStatusUpdated,
     [self, priv](const std::string& uid, uint64_t msgId, lrc::api::interaction::Info msg) {
         if (!priv->conversation_) return;
-        if(uid == priv->conversation_->uid) {
+        if (uid == priv->conversation_->uid) {
             update_interaction(self, msgId, msg);
         }
     });
 
+    priv->interaction_removed = QObject::connect(
+    &*(*priv->accountInfo_)->conversationModel, &lrc::api::ConversationModel::interactionRemoved,
+    [self, priv](const std::string& convUid, uint64_t interactionId) {
+        if (!priv->conversation_) return;
+        if (convUid == priv->conversation_->uid) {
+            remove_interaction(self, interactionId);
+        }
+    });
+
     if (!priv->conversation_) return;
     auto contactUri = priv->conversation_->participants.front();
     try {
diff --git a/src/webkitchatcontainer.cpp b/src/webkitchatcontainer.cpp
index 35b51c48ed409d577dca7c9e64accdd9fe0f5d51..0f950080d6e76da3c1bdea86e21fee55a3de251a 100644
--- a/src/webkitchatcontainer.cpp
+++ b/src/webkitchatcontainer.cpp
@@ -632,6 +632,23 @@ webkit_chat_container_update_interaction(WebKitChatContainer *view,
     g_free(function_call);
 }
 
+void
+webkit_chat_container_remove_interaction(WebKitChatContainer *view, uint64_t interactionId)
+{
+    WebKitChatContainerPrivate *priv = WEBKIT_CHAT_CONTAINER_GET_PRIVATE(view);
+
+    gchar* function_call = g_strdup_printf("removeInteraction(%i);", interactionId);
+    webkit_web_view_run_javascript(
+        WEBKIT_WEB_VIEW(priv->webview_chat),
+        function_call,
+        NULL,
+        NULL,
+        NULL
+    );
+    g_free(function_call);
+}
+
+
 void
 webkit_chat_container_print_new_interaction(WebKitChatContainer *view,
                                             lrc::api::ConversationModel& conversation_model,
diff --git a/src/webkitchatcontainer.h b/src/webkitchatcontainer.h
index b906ff622fe91d7a3a92233ebc8a6242c7ed3384..1f22d286c245b5322fbc12f1f3b12b8930853bee 100644
--- a/src/webkitchatcontainer.h
+++ b/src/webkitchatcontainer.h
@@ -48,6 +48,7 @@ void       webkit_chat_container_clear                (WebKitChatContainer *view
 void       webkit_chat_container_clear_sender_images  (WebKitChatContainer *view);
 void       webkit_chat_container_print_new_interaction(WebKitChatContainer *view, lrc::api::ConversationModel& conversation_model, uint64_t msgId, const lrc::api::interaction::Info& interaction);
 void       webkit_chat_container_update_interaction   (WebKitChatContainer *view, lrc::api::ConversationModel& conversation_model, uint64_t msgId, const lrc::api::interaction::Info& interaction);
+void       webkit_chat_container_remove_interaction   (WebKitChatContainer *view, uint64_t interactionId);
 void       webkit_chat_container_print_history        (WebKitChatContainer *view, lrc::api::ConversationModel& conversation_model, const std::map<uint64_t, lrc::api::interaction::Info> interactions);
 void       webkit_chat_container_set_sender_image     (WebKitChatContainer *view, const std::string& sender, const std::string& senderImage);
 gboolean   webkit_chat_container_is_ready             (WebKitChatContainer *view);
diff --git a/web/chatview.css b/web/chatview.css
index 85083f610a97f279da017de23390bb8d85ff6a16..2c41798ddbe3e695350907fc48f3e4fe4513a543 100644
--- a/web/chatview.css
+++ b/web/chatview.css
@@ -391,13 +391,71 @@ a:hover {
   -webkit-user-select: auto;
 }
 
+.menu_interaction
+{
+    margin: 5px;
+    padding: 10px;
+    padding-top: 0;
+    opacity: 0;
+    height: 20px;
+    transition:visibility 0.3s linear,opacity 0.3s linear;
+}
+
+.message_type_contact .menu_interaction
+{
+    display: none;
+    visibility: hidden;
+}
+
+.message_type_call .menu_interaction
+{
+    margin: auto;
+    padding: 0;
+    vertical-align: center;
+}
+
+.message_type_call .menu_interaction .dropdown
+{
+    margin-top: -17px;
+}
+
+.message:hover .menu_interaction
+{
+    display: block;
+    opacity: 1;
+}
+
+.dropdown {
+    display: none;
+    z-index: 1;
+    position: absolute;
+    background-color: #fff;
+    padding-top: 3px;
+    padding-bottom: 3px;
+}
+
+.dropdown div
+{
+    color: #111;
+    padding: 10px;
+}
+
+.dropdown div:hover
+{
+    background-color: #ddd;
+}
+
+#showmenu:checked ~ .dropdown{
+    display:block;
+}
+
 .message_in {
-  padding-left: 25%;
+    padding-left: 25%;
 }
 
 .message_out {
-  padding-right: 25%;
-  flex-direction: row-reverse;
+    padding-right: 25%;
+    flex-direction: row-reverse;
 }
 
 .message_in + .message_in .sender_image {
@@ -530,52 +588,52 @@ a:hover {
 }
 
 .timestamp {
-  display: flex;
-  justify-content: flex-start;
-  color: #333;
-  font-size: 10px;
-  padding: 5px;
+    display: flex;
+    justify-content: flex-start;
+    color: #333;
+    font-size: 10px;
+    padding: 5px;
 }
 
 .timestamp_out {
-  flex-direction: row-reverse;
+    flex-direction: row-reverse;
 }
 
 /* Buttons */
 
 .flat-button {
-  flex: 1;
-  padding: 0;
+    flex: 1;
+    padding: 0;
 }
 
 .left_buttons {
-  display: flex;
-  align-self: center;
-  max-width: 90px;
-  padding-left: 1em;
+    display: flex;
+    align-self: center;
+    max-width: 90px;
+    padding-left: 1em;
 }
 
 /* Status */
 
 .status_circle {
-  fill: #A0A0A0;
-  -webkit-animation: circle-dance;
-  -webkit-animation-duration: 0.8s;
-  -webkit-animation-iteration-count: infinite;
-  -webkit-animation-direction: alternate;
-  -webkit-animation-timing-function: ease-in-out;
+    fill: #A0A0A0;
+    -webkit-animation: circle-dance;
+    -webkit-animation-duration: 0.8s;
+    -webkit-animation-iteration-count: infinite;
+    -webkit-animation-direction: alternate;
+    -webkit-animation-timing-function: ease-in-out;
 }
 
 .anim-first {
-  -webkit-animation-delay: 0.7s;
+    -webkit-animation-delay: 0.7s;
 }
 
 .anim-second {
-  -webkit-animation-delay: 0.9s;
+    -webkit-animation-delay: 0.9s;
 }
 
 .anim-third {
-  -webkit-animation-delay: 1.1s;
+    -webkit-animation-delay: 1.1s;
 }
 
 @-webkit-keyframes circle-dance {
@@ -590,20 +648,20 @@ a:hover {
 }
 
 .status-x {
-  stroke-dasharray: 12;
-  stroke-dashoffset: 12;
-  -webkit-animation: dash-x;
-  -webkit-animation-duration: 0.2s;
-  -webkit-animation-fill-mode: forwards;
-  -webkit-animation-timing-function: ease-in-out;
+    stroke-dasharray: 12;
+    stroke-dashoffset: 12;
+    -webkit-animation: dash-x;
+    -webkit-animation-duration: 0.2s;
+    -webkit-animation-fill-mode: forwards;
+    -webkit-animation-timing-function: ease-in-out;
 }
 
 .x-first {
-  -webkit-animation-delay: 0.7s;
+    -webkit-animation-delay: 0.7s;
 }
 
 .x-second {
-  -webkit-animation-delay: 0.9s;
+    -webkit-animation-delay: 0.9s;
 }
 
 @-webkit-keyframes dash-x{
@@ -618,13 +676,13 @@ a:hover {
 /* Contact + Call interactions */
 .message_type_contact .message_wrapper,
 .message_type_call .message_wrapper {
-  width: auto;
-  margin-left: 30%;
-  margin-right: 30%;
-  display: flex;
-  flex-wrap: wrap;
-  background-color: #f2f2f2;
-  padding: 0;
+    width: auto;
+    margin-left: 30%;
+    margin-right: 30%;
+    display: flex;
+    flex-wrap: wrap;
+    background-color: #f2f2f2;
+    padding: 0;
 }
 
 .message_type_contact .message_wrapper:before,
@@ -639,94 +697,94 @@ a:hover {
 
 .message_type_contact .text,
 .message_type_call .text {
-  align-self: center;
-  font-size: 1.2em;
-  padding: 1em;
+    align-self: center;
+    font-size: 1.2em;
+    padding: 1em;
 }
 
 /* file interactions */
 
 .message_type_data_transfer .message_wrapper {
-  padding: 0;
-  width: 30%;
-  display: flex;
-  flex-wrap: wrap;
+    padding: 0;
+    width: 30%;
+    display: flex;
+    flex-wrap: wrap;
 }
 
 .accept, .refuse {
-  border-radius: 50%;
-  cursor: pointer;
+    border-radius: 50%;
+    cursor: pointer;
 }
 
 .accept svg,
 .refuse svg {
-  padding: 8px;
-  width: 24px;
-  height: 24px;
+    padding: 8px;
+    width: 24px;
+    height: 24px;
 }
 
 .accept {
-  fill: #219d55;
+    fill: #219d55;
 }
 
 .accept:hover {
-  fill: white;
-  background: #219d55;
+    fill: white;
+    background: #219d55;
 }
 
 .refuse {
-  fill: #dc2719;
+    fill: #dc2719;
 }
 
 .refuse:hover {
-  fill: white;
-  background: #dc2719;
+    fill: white;
+    background: #dc2719;
 }
 
 .message_type_data_transfer .text {
-  padding: 1em;
-  text-align: left;
-  align-self: left;
-  max-width: calc(100% - 180px);
+    padding: 1em;
+    text-align: left;
+    align-self: left;
+    max-width: calc(100% - 180px);
 }
 
 .message_type_data_transfer .filename {
-  cursor: pointer;
-  font-size: 1.1em;
-  overflow: hidden;
+    cursor: pointer;
+    font-size: 1.1em;
+    overflow: hidden;
 }
 
 .message_type_data_transfer .informations {
-  color: #555;
-  font-size: 0.8em;
+    color: #555;
+    font-size: 0.8em;
 }
 
 .message_progress_bar {
-  width: 100%;
-  height: 1em;
-  position: relative;
-  overflow: hidden;
-  background-color: #eee;
-  border-radius: 0;
-  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
+    width: 100%;
+    height: 1em;
+    position: relative;
+    overflow: hidden;
+    background-color: #eee;
+    border-radius: 0;
+    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;
 }
 
 .message_progress_bar > span {
-  display: inline;
-  height: 100%;
-  background-color: #01a2b8;
-  position: absolute;
-  overflow: hidden;
+    display: inline;
+    height: 100%;
+    background-color: #01a2b8;
+    position: absolute;
+    overflow: hidden;
 }
 
 /* text interactions */
 
 .message_type_text .message_wrapper {
-  max-width: 40%;
+    max-width: 40%;
 }
 
 .message_type_text .message_text {
-  padding: 0px;
+    padding: 0px;
 }
 
 .message_text {
@@ -737,110 +795,124 @@ a:hover {
 }
 
 pre {
-  font : inherit;
-  font-family : inherit;
-  font-size : inherit;
-  font-style : inherit;
-  font-variant : inherit;
-  font-weight : inherit;
-  margin: 0;
-  padding: 0;
+    font : inherit;
+    font-family : inherit;
+    font-size : inherit;
+    font-style : inherit;
+    font-variant : inherit;
+    font-weight : inherit;
+    margin: 0;
+    padding: 0;
 }
 
 /* Media interactions */
 .media_wrapper img {
-  max-width: 800px;
-  max-height: 700px;
-  margin: 5px 0 0 0;
-  border-radius: 10px;
+    max-width: 800px;
+    max-height: 700px;
+    margin: 5px 0 0 0;
+    border-radius: 10px;
 }
 
 .playVideo {
-  background-color: rgba(0, 0, 0, 0.6);
-  height: 50px;
-  width: 50px;
-  border-radius: 5px;
-  float: right;
-  position: absolute;
-  top: calc(50% - 25px);
-  left: calc(50% - 25px);
-  z-index: 3;
+    background-color: rgba(0, 0, 0, 0.6);
+    height: 50px;
+    width: 50px;
+    border-radius: 5px;
+    float: right;
+    position: absolute;
+    top: calc(50% - 25px);
+    left: calc(50% - 25px);
+    z-index: 3;
 }
 
 .containerVideo {
-  width: 100%;
-  position: relative;
+    width: 100%;
+    position: relative;
 }
 
 .playVideo svg {
-  height: 40px;
-  width: 40px;
-  margin: 5px;
+    height: 40px;
+    width: 40px;
+    margin: 5px;
 }
 
 /* Text interaction */
 .failure,
 .sending {
-  margin: 10px 10px;
-  color: #A0A0A0;
-  opacity: 0;
-  -webkit-animation-name: fade-in;
-  -webkit-animation-duration: 0.2s;
-  -webkit-animation-timing-function: ease-in-out;
-  -webkit-animation-delay: 0.4s;
-  -webkit-animation-fill-mode: forwards;
-  transition: opacity 0.5s ease-in-out;
+    margin: 10px 10px;
+    color: #A0A0A0;
+    opacity: 0;
+    -webkit-animation-name: fade-in;
+    -webkit-animation-duration: 0.2s;
+    -webkit-animation-timing-function: ease-in-out;
+    -webkit-animation-delay: 0.4s;
+    -webkit-animation-fill-mode: forwards;
+    transition: opacity 0.5s ease-in-out;
 }
 
 /* Classic screens */
 @media screen and (max-width: 1920px), screen and (max-height: 1080px) {
   .message_in {
-    padding-left: 15%;
+      padding-left: 15%;
   }
 
   .message_out {
-    padding-right: 15%;
+      padding-right: 15%;
   }
 
   .message_type_text .message_wrapper {
-    max-width: 60%;
+      max-width: 60%;
   }
 
   /* File interactions */
   .message_type_data_transfer .message_wrapper {
-    width: 40%;
+      width: 40%;
   }
 
   /* Media interactions */
   .media_wrapper img {
-    max-width: 450px;
-    max-height: 450px;
+      max-width: 450px;
+      max-height: 450px;
+  }
+
+  .menu_interaction
+  {
+      margin: 5px;
+      padding: 2px;
+      height: 10px;
+      font-size: 0.7em;
+      transition:visibility 0.3s linear,opacity 0.3s linear;
   }
 }
 
 /* lower resolutions */
 @media screen and (max-width: 1000px), screen and (max-height: 480px) {
   .message_in {
-    padding-left: 0;
+      padding-left: 0;
   }
 
   .message_out {
-    padding-right: 0;
+      padding-right: 0;
+  }
+
+  .message_type_contact,
+  .message_type_call {
+      max-width: 100%;
   }
 
   .message_type_text .message_wrapper {
-    max-width: 90%;
+      max-width: 90%;
   }
 
   /* File interactions */
   .message_type_data_transfer .message_wrapper {
-    width: 70%;
+      width: 70%;
   }
 
   /* Media interactions */
   .media_wrapper img {
-    max-width: 200px;
-    max-height: 200px;
+      max-width: 200px;
+      max-height: 200px;
   }
 }
 
@@ -853,24 +925,24 @@ pre {
 
   /* File interactions */
   .message_type_data_transfer .left_buttons {
-    max-width: 100%;
+      max-width: 100%;
   }
 
   .message_type_data_transfer .text {
-    max-width: 100%;
-    padding-left: 0;
+      max-width: 100%;
+      padding-left: 0;
   }
 }
 
 .message_type_contact .message_wrapper:hover .timestamp_action,
 .message_type_call .message_wrapper:hover .timestamp_action {
-  opacity: 1;
+    opacity: 1;
 }
 
 .timestamp_action {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  opacity:0;
-  transition:visibility 0.3s linear,opacity 0.3s linear;
+    margin: auto;
+    padding: 0;
+    vertical-align: center;
+    opacity:0;
+    transition:visibility 0.3s linear,opacity 0.3s linear;
 }
diff --git a/web/chatview.html b/web/chatview.html
index fec9979c5a14c173c94fc7802b37877fd52d5163..46af2c11b7c1fc59a2d84532f9453cab6ec1880a 100644
--- a/web/chatview.html
+++ b/web/chatview.html
@@ -879,7 +879,7 @@ function updateTextInteraction(message_div, delivery_status) {
             sending.setAttribute("class", "sending")
             sending.innerHTML = "<svg overflow=\"hidden\" viewBox=\"0 -2 16 14\" height=\"16px\" width=\"16px\"><circle class=\"status_circle anim-first\" cx=\"4\" cy=\"12\" r=\"1\"/><circle class=\"status_circle anim-second\" cx=\"8\" cy=\"12\" r=\"1\"/><circle class=\"status_circle anim-third\" cx=\"12\" cy=\"12\" r=\"1\"/></svg>"
             // add sending animation to message;
-            message_div.appendChild(sending)
+            message_div.insertBefore(sending, message_div.querySelector(".menu_interaction"))
         }
         message_div.querySelector(".message_text").style = "color: #888"
         break
@@ -893,7 +893,7 @@ function updateTextInteraction(message_div, delivery_status) {
             failure_div.setAttribute("class", "failure")
             failure_div.innerHTML = "<svg overflow=\"visible\" viewBox=\"0 -2 16 14\" height=\"16px\" width=\"16px\"><path class=\"status-x x-first\" stroke=\"#AA0000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"3\" fill=\"none\" d=\"M4,4 L12,12\"/><path class=\"status-x x-second\" stroke=\"#AA0000\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"3\" fill=\"none\" d=\"M12,4 L4,12\"/></svg>"
             // add failure animation to message
-            message_div.appendChild(failure_div)
+            message_div.insertBefore(failure_div, message_div.querySelector(".menu_interaction"))
         }
         if (sending) sending.style.display = "none"
         break
@@ -979,6 +979,28 @@ function updateContactInteraction(message_div, message_object) {
     left_buttons.appendChild(status_button)
 }
 
+/**
+ * Remove an interaction from the conversation
+ * @param interaction_id
+ */
+/* exported removeInteraction */
+function removeInteraction(interaction_id) {
+    var interaction = document.querySelector(`#message_${interaction_id}`)
+    var child = interaction
+    var messages = document.querySelector("#messages")
+    var i = 0
+    while( (child = child.previousSibling) != null )
+        i++
+    if (interaction)  interaction.parentNode.removeChild(interaction)
+    if (i < messages.children.length) {
+        var timestampAfter = messages.children[i].classList.contains("timestamp")
+        var timestampBefore = messages.children[i].classList.contains("timestamp")
+        if (timestampAfter && timestampBefore) {
+            messages.children[i].parentNode.removeChild(messages.children[i])
+        }
+    }
+}
+
 /**
  * Add a message to the conversation.
  * @param message_object to treat
@@ -1064,6 +1086,44 @@ function addOrUpdateMessage(message_object, new_message, insert_after = true) {
             message_div.appendChild(temp)
         }
 
+        const menu_element = document.createElement("div")
+        menu_element.setAttribute("class", "menu_interaction")
+        menu_element.innerHTML = "<label for=\"showmenu\">\
+          <svg fill=\"#888888\" height=\"12\" viewBox=\"0 0 24 24\" width=\"12\" xmlns=\"http://www.w3.org/2000/svg\">\
+            <path d=\"M0 0h24v24H0z\" fill=\"none\"/>\
+            <path d=\"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z\"/>\
+          </svg>\
+        </label>\
+        <input type=\"checkbox\" id=\"showmenu\" hidden />"
+        menu_element.onclick = function() {
+            const button = this.querySelector("#showmenu")
+            button.checked = !button.checked
+        }
+        menu_element.onmouseleave = function() {
+            const button = this.querySelector("#showmenu")
+            button.checked = false
+        }
+        const dropdown = document.createElement("div")
+        const dropdown_classes = [
+            "dropdown",
+            `dropdown_${message_id}`
+        ]
+        dropdown.setAttribute("class", dropdown_classes.join(" "))
+        const remove = document.createElement("div")
+        remove.innerHTML = "Delete"
+        remove.msg_id = message_id
+        remove.onclick = function() {
+            window.prompt(`DELETE_INTERACTION:${this.msg_id}`)
+        }
+        dropdown.appendChild(remove)
+        menu_element.appendChild(dropdown)
+        if (message_type !== "call") {
+            message_div.appendChild(menu_element)
+        } else {
+            var wrapper = message_div.querySelector(".message_wrapper")
+            wrapper.insertBefore(menu_element, wrapper.firstChild)
+        }
+
         // Get timestamp to add
         const formattedTimestamp = getMessageTimestampText(message_timestamp, true)
         // Create the timestamp object