Skip to content
Snippets Groups Projects
Commit d2ea6ddc authored by Sébastien Blin's avatar Sébastien Blin
Browse files

chatview: add the ability to remove one interaction from history


Change-Id: I27a0ec40c3215f966a3637f681845b196f5418d7
Reviewed-by: default avatarPhilippe Gorley <philippe.gorley@savoirfairelinux.com>
parent 396212d2
Branches
No related tags found
No related merge requests found
...@@ -60,6 +60,7 @@ struct _ChatViewPrivate ...@@ -60,6 +60,7 @@ struct _ChatViewPrivate
AccountInfoPointer const * accountInfo_; AccountInfoPointer const * accountInfo_;
QMetaObject::Connection new_interaction_connection; QMetaObject::Connection new_interaction_connection;
QMetaObject::Connection interaction_removed;
QMetaObject::Connection update_interaction_connection; QMetaObject::Connection update_interaction_connection;
QMetaObject::Connection update_add_to_conversations; QMetaObject::Connection update_add_to_conversations;
...@@ -90,6 +91,7 @@ chat_view_dispose(GObject *object) ...@@ -90,6 +91,7 @@ chat_view_dispose(GObject *object)
QObject::disconnect(priv->new_interaction_connection); QObject::disconnect(priv->new_interaction_connection);
QObject::disconnect(priv->update_interaction_connection); QObject::disconnect(priv->update_interaction_connection);
QObject::disconnect(priv->interaction_removed);
QObject::disconnect(priv->update_add_to_conversations); QObject::disconnect(priv->update_add_to_conversations);
/* Destroying the box will also destroy its children, and we wouldn't /* 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 ...@@ -269,6 +271,14 @@ webkit_chat_container_script_dialog(GtkWidget* webview, gchar *interaction, Chat
} }
} else if (order.find("ADD_TO_CONVERSATIONS") == 0) { } else if (order.find("ADD_TO_CONVERSATIONS") == 0) {
button_add_to_conversations_clicked(self); 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 ...@@ -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 static void
load_participants_images(ChatView *self) load_participants_images(ChatView *self)
{ {
...@@ -429,6 +449,15 @@ webkit_chat_container_ready(ChatView* self) ...@@ -429,6 +449,15 @@ webkit_chat_container_ready(ChatView* self)
} }
}); });
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; if (!priv->conversation_) return;
auto contactUri = priv->conversation_->participants.front(); auto contactUri = priv->conversation_->participants.front();
try { try {
......
...@@ -632,6 +632,23 @@ webkit_chat_container_update_interaction(WebKitChatContainer *view, ...@@ -632,6 +632,23 @@ webkit_chat_container_update_interaction(WebKitChatContainer *view,
g_free(function_call); 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 void
webkit_chat_container_print_new_interaction(WebKitChatContainer *view, webkit_chat_container_print_new_interaction(WebKitChatContainer *view,
lrc::api::ConversationModel& conversation_model, lrc::api::ConversationModel& conversation_model,
......
...@@ -48,6 +48,7 @@ void webkit_chat_container_clear (WebKitChatContainer *view ...@@ -48,6 +48,7 @@ void webkit_chat_container_clear (WebKitChatContainer *view
void webkit_chat_container_clear_sender_images (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_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_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_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); 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); gboolean webkit_chat_container_is_ready (WebKitChatContainer *view);
......
...@@ -391,6 +391,64 @@ a:hover { ...@@ -391,6 +391,64 @@ a:hover {
-webkit-user-select: auto; -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 { .message_in {
padding-left: 25%; padding-left: 25%;
} }
...@@ -816,6 +874,15 @@ pre { ...@@ -816,6 +874,15 @@ pre {
max-width: 450px; max-width: 450px;
max-height: 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 */ /* lower resolutions */
...@@ -828,6 +895,11 @@ pre { ...@@ -828,6 +895,11 @@ pre {
padding-right: 0; padding-right: 0;
} }
.message_type_contact,
.message_type_call {
max-width: 100%;
}
.message_type_text .message_wrapper { .message_type_text .message_wrapper {
max-width: 90%; max-width: 90%;
} }
...@@ -868,9 +940,9 @@ pre { ...@@ -868,9 +940,9 @@ pre {
} }
.timestamp_action { .timestamp_action {
display: flex; margin: auto;
align-items: center; padding: 0;
justify-content: center; vertical-align: center;
opacity:0; opacity:0;
transition:visibility 0.3s linear,opacity 0.3s linear; transition:visibility 0.3s linear,opacity 0.3s linear;
} }
...@@ -879,7 +879,7 @@ function updateTextInteraction(message_div, delivery_status) { ...@@ -879,7 +879,7 @@ function updateTextInteraction(message_div, delivery_status) {
sending.setAttribute("class", "sending") 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>" 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; // 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" message_div.querySelector(".message_text").style = "color: #888"
break break
...@@ -893,7 +893,7 @@ function updateTextInteraction(message_div, delivery_status) { ...@@ -893,7 +893,7 @@ function updateTextInteraction(message_div, delivery_status) {
failure_div.setAttribute("class", "failure") 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>" 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 // 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" if (sending) sending.style.display = "none"
break break
...@@ -979,6 +979,28 @@ function updateContactInteraction(message_div, message_object) { ...@@ -979,6 +979,28 @@ function updateContactInteraction(message_div, message_object) {
left_buttons.appendChild(status_button) 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. * Add a message to the conversation.
* @param message_object to treat * @param message_object to treat
...@@ -1064,6 +1086,44 @@ function addOrUpdateMessage(message_object, new_message, insert_after = true) { ...@@ -1064,6 +1086,44 @@ function addOrUpdateMessage(message_object, new_message, insert_after = true) {
message_div.appendChild(temp) 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 // Get timestamp to add
const formattedTimestamp = getMessageTimestampText(message_timestamp, true) const formattedTimestamp = getMessageTimestampText(message_timestamp, true)
// Create the timestamp object // Create the timestamp object
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment