From c76e4859dcb69090ccf31ed8fe6140e4eaa567d2 Mon Sep 17 00:00:00 2001 From: Mohammad Warid <58583793+waridrox@users.noreply.github.com> Date: Fri, 11 Jun 2021 20:11:14 +0530 Subject: [PATCH] Added animation to save icon when user enters a comment text (#9384) * Added animation to save icon when user enters a comment text * Edge case handled * Updated tests for save and recover buttons * Update editorToolbar.js * Unnecessary semicolon * ESLint typeof operator * let instead of var * Matched padding of saving text with file upload text --- app/assets/javascripts/editor.js | 66 +++++++++++++++++++++++-- app/assets/javascripts/editorToolbar.js | 49 ++++++++++++++++-- test/system/comment_test.rb | 6 +++ 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/editor.js b/app/assets/javascripts/editor.js index b57fb5a196..58aed69324 100644 --- a/app/assets/javascripts/editor.js +++ b/app/assets/javascripts/editor.js @@ -104,16 +104,74 @@ class Editor { // h7() { // this.wrap('#######','') // } + + //debounce function addition + debounce(func, wait, immediate) { + let timeout; + return function () { + let context = this, + args = arguments; + let later = function () { + timeout = null; + if (!immediate) func.apply(context, args); + }; + let callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; + } + // this function is dedicated to Don Blair https://github.com/donblair attachSaveListener() { // remove any other existing eventHandler $("textarea").off("input.save"); // input.save is a custom jQuery eventHandler const thisEditor = this; // save a reference to this editor, because inside the eventListener, "this" points to e.target - this.textAreaElement.on("input.save", function() { + //implementing a debounce function on save method + this.textAreaElement.on( + "input.save", + debounce(function () { + //changing styles and text + //explicitly handling main comment form + if ($('#text-input-main').is(':focus')) { + + $("#comment-form-main .btn-toolbar #save-button-main").find("i").removeClass("fa fa-save").addClass("fas fa-sync fa-spin"); + + let saving_text = $('
Saving...
'); + $("#comment-form-main .imagebar").prepend(saving_text); + $("#comment-form-main .imagebar p").not("#saving-text").hide(); + + //adding delay and revering the styles + setTimeout(() => { + $("#comment-form-main .btn-toolbar #save-button-main").find("i").removeClass("fas fa-sync fa-spin").addClass("fa fa-save"); + + $("#comment-form-main .imagebar").find("#saving-text").remove(); + $("#comment-form-main .imagebar p").not("#saving-text").show(); + }, 400); + } + else { + //handling other comment forms + let comment_temp_id = (document.activeElement.parentElement.parentElement.id); + let imager_bar = (document.activeElement.nextElementSibling.className); + + $('#'+comment_temp_id).find('.btn-toolbar').find(".save-button").find("i").removeClass("fa fa-save").addClass("fas fa-sync fa-spin"); + + let saving_text = $('Saving...
'); + $('#'+comment_temp_id).find('.'+imager_bar).prepend(saving_text); + $('#'+comment_temp_id).find('.'+imager_bar).find("p").not("#saving-text").hide(); + + setTimeout(() => { + $('#'+comment_temp_id).find('.btn-toolbar').find(".save-button").find("i").removeClass("fas fa-sync fa-spin").addClass("fa fa-save"); + + $('#'+comment_temp_id).find('.'+imager_bar).find("#saving-text").remove(); + $('#'+comment_temp_id).find('.'+imager_bar).find("p").not("#saving-text").show(); + }, 400); + } thisEditor.save(thisEditor); - }); - } - save(thisEditor) { + }, 700) + ); + } + save(thisEditor) { const storageKey = "plots:" + window.location.pathname + ":" + thisEditor.commentFormID; localStorage.setItem(storageKey, thisEditor.textAreaValue); } diff --git a/app/assets/javascripts/editorToolbar.js b/app/assets/javascripts/editorToolbar.js index 448b63589a..14d4f67616 100644 --- a/app/assets/javascripts/editorToolbar.js +++ b/app/assets/javascripts/editorToolbar.js @@ -90,9 +90,52 @@ $(function() { }) // for save & recover buttons .on("click", ".save-button", function(e) { - $E.setState(e.currentTarget.dataset.formId); // string that is: "main", "reply-123", "edit-123" etc. - $E.save($E); - }) + //preventing multiple clicks on the button + if(!e.detail || e.detail === 1) { + //explicitly handling main comment section + if ((this.id) === "save-button-main") { + // toggling the favicon save icon class to add a spinner icon + $(this).find("i").toggleClass("fa fa-save fas fa-sync fa-spin"); + + //changing the text from "Upload an image" to "Saving..." + let saving_text = $('Saving...
'); + $("#comment-form-main .imagebar").prepend(saving_text); + $("#comment-form-main .imagebar p").not("#saving-text").hide(); + + //setting up delay and reverting the styles + setTimeout(() => { + $(this).find("i").toggleClass("fa fa-save fas fa-sync fa-spin"); + $("#comment-form-main .imagebar").find("#saving-text").remove(); + $("#comment-form-main .imagebar p").not("#saving-text").show(); + + $E.setState(e.currentTarget.dataset.formId); // string that is: "main", "reply-123", "edit-123" etc. + $E.save($E); + }, 400); + } + else { + //handling other comment sections + let comment_reply_id = (this.parentNode.parentNode.nextElementSibling.nextElementSibling.id); + + // toggling the favicon save icon class to add a spinner icon + $(this).find("i").toggleClass("fa fa-save fas fa-sync fa-spin"); + + //changing the text from "Upload an image" to "Saving..." + let saving_text = $('Saving...
'); + $('#'+comment_reply_id).find(".imagebar").prepend(saving_text); + $('#'+comment_reply_id).find(".imagebar p").not("#saving-text").hide(); + + //setting up delay and reverting the styles + setTimeout(() => { + $(this).find("i").toggleClass("fa fa-save fas fa-sync fa-spin"); + $('#'+comment_reply_id).find(".imagebar").find("#saving-text").remove(); + $('#'+comment_reply_id).find(".imagebar p").not("#saving-text").show(); + + $E.setState(e.currentTarget.dataset.formId); // string that is: "main", "reply-123", "edit-123" etc. + $E.save($E); + }, 400); + } + } + }) .on("click", ".recover-button", function(e) { $E.setState(e.currentTarget.dataset.formId); // string that is: "main", "reply-123", "edit-123" etc. $E.recover(); diff --git a/test/system/comment_test.rb b/test/system/comment_test.rb index 7651cbd47f..99a5339ca2 100644 --- a/test/system/comment_test.rb +++ b/test/system/comment_test.rb @@ -389,6 +389,8 @@ def get_path(page_type, path) page.find('#text-input-main') .click .fill_in with: comment_text_main + # taking into account the time for debounce function + sleep(0.7) # open up reply comment form page.all('p', text: 'Reply to this comment...')[0].click @@ -399,6 +401,8 @@ def get_path(page_type, path) page.find('#text-input-reply-' + reply_id_num) .click .fill_in with: comment_text_reply + # taking into account the time for debounce function + sleep(0.7) # open up edit comment form page.find(".edit-comment-btn").click @@ -409,6 +413,8 @@ def get_path(page_type, path) page.find('#text-input-edit-' + edit_id_num) .click .fill_in with: comment_text_edit + # taking into account the time for debounce function + sleep(0.7) # visit the page again (ie. refresh it) visit get_path(page_type, nodes(node_name).path)