diff --git a/cypress/integration/discussions.js b/cypress/integration/discussions.js index a6e0ff9b56..caf7d6c3f9 100644 --- a/cypress/integration/discussions.js +++ b/cypress/integration/discussions.js @@ -37,24 +37,24 @@ context('Discussions', () => { }; const reply_through_comment_box = () => { - cy.get('.discussion-on-page:visible .comment-field') + cy.get('.discussion-form:visible .comment-field') .type('This is a discussion from the cypress ui tests. \n\nThis comment was entered through the commentbox on the page.') .should('have.value', 'This is a discussion from the cypress ui tests. \n\nThis comment was entered through the commentbox on the page.'); - cy.get('.discussion-on-page:visible .submit-discussion').click(); + cy.get('.discussion-form:visible .submit-discussion').click(); cy.wait(3000); cy.get('.discussion-on-page:visible').should('have.class', 'show'); - cy.get('.discussion-on-page:visible').children(".reply-card").eq(1).children(".reply-text") + cy.get('.discussion-on-page:visible').children(".reply-card").eq(1).find(".reply-text") .should('have.text', 'This is a discussion from the cypress ui tests. \n\nThis comment was entered through the commentbox on the page.\n'); }; const cancel_and_clear_comment_box = () => { - cy.get('.discussion-on-page:visible .comment-field') + cy.get('.discussion-form:visible .comment-field') .type('This is a discussion from the cypress ui tests.') .should('have.value', 'This is a discussion from the cypress ui tests.'); - cy.get('.discussion-on-page:visible .cancel-comment').click(); - cy.get('.discussion-on-page:visible .comment-field').should('have.value', ''); + cy.get('.discussion-form:visible .cancel-comment').click(); + cy.get('.discussion-form:visible .comment-field').should('have.value', ''); }; const single_thread_discussion = () => { @@ -62,13 +62,13 @@ context('Discussions', () => { cy.get('.discussions-sidebar').should('have.length', 0); cy.get('.reply').should('have.length', 0); - cy.get('.discussion-on-page .comment-field') + cy.get('.discussion-form:visible .comment-field') .type('This comment is being made on a single thread discussion.') .should('have.value', 'This comment is being made on a single thread discussion.'); - cy.get('.discussion-on-page .submit-discussion').click(); + cy.get('.discussion-form:visible .submit-discussion').click(); cy.wait(3000); - cy.get('.discussion-on-page').children(".reply-card").eq(-1).children(".reply-text") + cy.get('.discussion-on-page').children(".reply-card").eq(-1).find(".reply-text") .should('have.text', 'This comment is being made on a single thread discussion.\n'); }; diff --git a/frappe/public/scss/website/index.scss b/frappe/public/scss/website/index.scss index 4352301b4c..0c96c62c17 100644 --- a/frappe/public/scss/website/index.scss +++ b/frappe/public/scss/website/index.scss @@ -88,6 +88,20 @@ border-radius: $dropdown-border-radius; } +.dropdown-item:active { + color: var(--fg-color); + text-decoration: none; + background-color: var(--gray-600); +} + +.dropdown-item:active:hover { + color: var(--fg-color); +} + +.dropdown-menu a:hover { + cursor: pointer; +} + .input-dark { background-color: $dark; border-color: darken($primary, 40%); diff --git a/frappe/templates/discussions/button.html b/frappe/templates/discussions/button.html index 8e61d2412f..746227aa0b 100644 --- a/frappe/templates/discussions/button.html +++ b/frappe/templates/discussions/button.html @@ -1,9 +1,6 @@ {% if frappe.session.user != "Guest" and (condition is not defined or (condition is defined and condition )) %} - + {{ _(cta_title) }} - - {% endif %} diff --git a/frappe/templates/discussions/comment_box.html b/frappe/templates/discussions/comment_box.html index ba8f440ad4..23c1bbecf1 100644 --- a/frappe/templates/discussions/comment_box.html +++ b/frappe/templates/discussions/comment_box.html @@ -28,7 +28,7 @@ {{ _("Cancel") }} -
+
{{ _("Post") }}
diff --git a/frappe/templates/discussions/discussions.js b/frappe/templates/discussions/discussions.js index 19c0f89a49..c786583fa6 100644 --- a/frappe/templates/discussions/discussions.js +++ b/frappe/templates/discussions/discussions.js @@ -4,8 +4,6 @@ frappe.ready(() => { add_color_to_avatars(); - expand_first_discussion(); - $(".search-field").keyup((e) => { search_topic(e); }); @@ -14,11 +12,11 @@ frappe.ready(() => { show_new_topic_modal(e); }); - $("#login-from-discussion").click((e) => { + $(".login-from-discussion").click((e) => { login_from_discussion(e); }); - $(".sidebar-topic").click((e) => { + $(".sidebar-parent").click((e) => { if ($(e.currentTarget).attr("aria-expanded") == "true") { e.stopPropagation(); } @@ -31,17 +29,6 @@ frappe.ready(() => { } }); - $(document).on("input", ".discussion-on-page .comment-field", (e) => { - if ($(e.currentTarget).val()) { - $(e.currentTarget).css("height", "48px"); - $(".cancel-comment").removeClass("hide").addClass("show"); - $(e.currentTarget).css("height", $(e.currentTarget).prop("scrollHeight")); - } else { - $(".cancel-comment").removeClass("show").addClass("hide"); - $(e.currentTarget).css("height", "48px"); - } - }); - $(document).on("click", ".submit-discussion", (e) => { submit_discussion(e); }); @@ -50,16 +37,26 @@ frappe.ready(() => { clear_comment_box(); }); - if ($(document).width() <= 550) { - $(document).on("click", ".sidebar-parent", () => { - hide_sidebar(); - }); - } + $(document).on("click", ".sidebar-parent", () => { + hide_sidebar(); + }); - $(document).on("click", ".back", (e) => { + $(document).on("click", ".back-button", (e) => { back_to_sidebar(e); }); + $(document).on("click", ".dismiss-reply", (e) => { + dismiss_reply(e); + }); + + $(document).on("click", ".reply-card .dropdown-menu", (e) => { + perform_action(e); + }); + + $(document).on("input", ".discussion-on-page .comment-field", (e) => { + adjust_comment_box(e); + }); + }); const show_new_topic_modal = (e) => { @@ -79,10 +76,17 @@ const setup_socket_io = () => { if (window.dev_server) { frappe.boot.socketio_port = "9000"; } + frappe.socketio.init(9000); frappe.socketio.socket.on("publish_message", (data) => { publish_message(data); }); + frappe.socketio.socket.on("update_message", (data) => { + update_message(data); + }); + frappe.socketio.socket.on("delete_message", (data) => { + delete_message(data); + }); }); }; @@ -92,44 +96,47 @@ const publish_message = (data) => { const topic = data.topic_info; const single_thread = $(".is-single-thread").length; const first_topic = !$(".reply-card").length; - const document_match_found = doctype == topic.reference_doctype && docname == topic.reference_docname; + const document_match_found = (doctype == topic.reference_doctype) && (docname == topic.reference_docname); + + post_message_cleanup(); + data.template = hide_actions_on_conditions(data.template, data.reply_owner); + data.template = style_avatar_frame(data.template); + data.sidebar = style_avatar_frame(data.sidebar); + data.new_topic_template = style_avatar_frame(data.new_topic_template); if ($(`.discussion-on-page[data-topic=${topic.name}]`).length) { - post_message_cleanup(); - data.template = style_avatar_frame(data.template); - $('
' + data.template) - .insertBefore(`.discussion-on-page[data-topic=${topic.name}] .discussion-form`); + $(data.template).insertBefore(`.discussion-on-page[data-topic=${topic.name}] .discussion-form`); } else if (!first_topic && !single_thread && document_match_found) { - post_message_cleanup(); - data.new_topic_template = style_avatar_frame(data.new_topic_template); - - $(data.sidebar).insertAfter(`.discussions-sidebar .form-group`); + $(data.sidebar).insertBefore($(`.discussions-sidebar .sidebar-parent`).first()); $(`#discussion-group`).prepend(data.new_topic_template); - if (topic.owner == frappe.session.user) { $(".discussion-on-page") && $(".discussion-on-page").collapse(); - $(".sidebar-topic").first().click(); + $(".sidebar-parent").first().click(); } } else if (single_thread && document_match_found) { - post_message_cleanup(); - data.template = style_avatar_frame(data.template); $(data.template).insertBefore(`.discussion-form`); $(".discussion-on-page").attr("data-topic", topic.name); } else if (topic.owner == frappe.session.user && document_match_found) { - post_message_cleanup(); window.location.reload(); } update_reply_count(topic.name); }; +const update_message = (data) => { + const reply_card = $(`[data-reply=${data.reply_name}]`); + reply_card.find(".reply-body").removeClass("hide"); + reply_card.find(".reply-edit-card").addClass("hide"); + reply_card.find(".reply-text").html(data.reply); + reply_card.find(".reply-actions").addClass("hide"); +}; + const post_message_cleanup = () => { $(".topic-title").val(""); - $(".comment-field").val(""); - $(".discussion-on-page .comment-field").css("height", "48px"); + $(".discussion-form .comment-field").val(""); $("#discussion-modal").modal("hide"); $("#no-discussions").addClass("hide"); $(".cancel-comment").addClass("hide"); @@ -141,15 +148,6 @@ const update_reply_count = (topic) => { $(`[data-target='#t${topic}']`).find(".reply-count").text(reply_count); }; -const expand_first_discussion = () => { - if ($(document).width() > 550) { - $($(".discussions-parent .collapse")[0]).addClass("show"); - $($(".discussions-sidebar [data-toggle='collapse']")[0]).attr("aria-expanded", true); - } else { - $("#discussion-group").addClass("hide"); - } -}; - const search_topic = (e) => { let input = $(e.currentTarget).val(); @@ -160,7 +158,7 @@ const search_topic = (e) => { } topics.each((i, elem) => { - let topic_id = $(elem).parent().attr("data-target"); + let topic_id = $(elem).closest(".sidebar-parent").attr("data-target"); /* Check match in replies */ let match_in_reply = false; @@ -201,16 +199,20 @@ const submit_discussion = (e) => { e.preventDefault(); e.stopImmediatePropagation(); + const target = $(e.currentTarget); + const reply_name = target.closest(".reply-card").data("reply"); const title = $(".topic-title:visible").length ? $(".topic-title:visible").val().trim() : ""; - const reply = $(".comment-field:visible").val().trim(); + let reply = reply_name ? target.closest(".reply-card") : target.closest(".discussion-form"); + reply = reply.find(".comment-field").val().trim(); if (reply) { - let doctype = $(e.currentTarget).closest(".discussions-parent").attr("data-doctype"); + let doctype = target.closest(".discussions-parent").attr("data-doctype"); doctype = doctype ? decodeURIComponent(doctype) : doctype; - let docname = $(e.currentTarget).closest(".discussions-parent").attr("data-docname"); + let docname = target.closest(".discussions-parent").attr("data-docname"); docname = docname ? decodeURIComponent(docname) : docname; + frappe.call({ method: "frappe.website.doctype.discussion_topic.discussion_topic.submit_discussion", args: { @@ -218,7 +220,8 @@ const submit_discussion = (e) => { "docname": docname ? docname : "", "reply": reply, "title": title, - "topic_name": $(e.currentTarget).closest(".discussion-on-page").attr("data-topic") + "topic_name": target.closest(".discussion-on-page").attr("data-topic"), + "reply_name": reply_name } }); } @@ -252,18 +255,64 @@ const style_avatar_frame = (template) => { }; const clear_comment_box = () => { - $(".discussion-on-page .comment-field").val(""); + $(".discussion-form .comment-field").val(""); $(".cancel-comment").removeClass("show").addClass("hide"); - $(".discussion-on-page .comment-field").css("height", "48px"); }; const hide_sidebar = () => { $(".discussions-sidebar").addClass("hide"); $("#discussion-group").removeClass("hide"); + $(".search-field").addClass("hide"); + $(".reply").addClass("hide"); }; const back_to_sidebar = () => { $(".discussions-sidebar").removeClass("hide"); $("#discussion-group").addClass("hide"); $(".discussion-on-page").collapse("hide"); + $(".search-field").removeClass("hide"); + $(".reply").removeClass("hide"); +}; + +const perform_action = (e) => { + const action = $(e.target).data().action; + const reply_card = $(e.target).closest(".reply-card"); + + if (action === "edit") { + reply_card.find(".reply-edit-card").removeClass("hide"); + reply_card.find(".reply-body").addClass("hide"); + reply_card.find(".reply-actions").removeClass("hide"); + } else if (action === "delete") { + frappe.call({ + method: "frappe.website.doctype.discussion_reply.discussion_reply.delete_message", + args: { + "reply_name": $(e.target).closest(".reply-card").data("reply") + } + }); + } +}; + +const dismiss_reply = (e) => { + const reply_card = $(e.currentTarget).closest(".reply-card"); + reply_card.find(".reply-edit-card").addClass("hide"); + reply_card.find(".reply-body").removeClass("hide"); + reply_card.find(".reply-actions").addClass("hide"); +}; + +const adjust_comment_box = (e) => { + if ($(e.currentTarget).val()) { + $(".cancel-comment").removeClass("hide").addClass("show"); + } else { + $(".cancel-comment").removeClass("show").addClass("hide"); + } +}; + +const hide_actions_on_conditions = (template, owner) => { + let $template = $(template); + frappe.session.user != owner && $template.find(".dropdown").addClass("hide"); + return $template.prop("outerHTML"); +}; + +const delete_message = (data) => { + $(`[data-reply=${data.reply_name}]`).addClass("hide"); }; diff --git a/frappe/templates/discussions/discussions_section.html b/frappe/templates/discussions/discussions_section.html index 07c229595b..5db7cf86b1 100644 --- a/frappe/templates/discussions/discussions_section.html +++ b/frappe/templates/discussions/discussions_section.html @@ -9,25 +9,31 @@
{{ _(title) }} + {% if topics | length and not single_thread %} + {% include "frappe/templates/discussions/search.html" %} + {% endif %} {% if topics and not single_thread %} {% include "frappe/templates/discussions/button.html" %} {% endif %}
-
+
{% if topics and not single_thread %} -
- {% include "frappe/templates/discussions/search.html" %} +
{% for topic in topics %} {% set replies = frappe.get_all("Discussion Reply", {"topic": topic.name})%} {% include "frappe/templates/discussions/sidebar.html" %} + + {% if loop.index != topics | length %} +
+ {% endif %} + {% endfor %}
-
+
{% for topic in topics %} {% include "frappe/templates/discussions/reply_section.html" %} {% endfor %} @@ -38,19 +44,25 @@ {% include "frappe/templates/discussions/reply_section.html" %} {% else %} -
- -
{{ empty_state_title }}
-
{{ empty_state_subtitle }}
- {% if frappe.session.user == "Guest" %} -
{{ _("Login") }}
- {% elif condition is defined and not condition %} -
- {{ button_name }} +
+
+ +
+
+
{{ empty_state_title }}
+
{{ empty_state_subtitle }}
+
+
+ {% if frappe.session.user == "Guest" %} + + {% elif condition is defined and not condition %} + + {% else %} + {% include "frappe/templates/discussions/button.html" %} + {% endif %}
- {% else %} - {% include "frappe/templates/discussions/button.html" %} - {% endif %}
{% endif %}
diff --git a/frappe/templates/discussions/reply_card.html b/frappe/templates/discussions/reply_card.html index 5ff5261472..d9eb1da25c 100644 --- a/frappe/templates/discussions/reply_card.html +++ b/frappe/templates/discussions/reply_card.html @@ -1,14 +1,50 @@ {% from "frappe/templates/includes/avatar_macro.html" import avatar %} -
+
{% set member = frappe.db.get_value("User", reply.owner, ["name", "full_name", "username"], as_dict=True) %} -
- {% if loop.index == 1 or single_thread %} + +
{{ avatar(reply.owner) }} - {% endif %} - + {{ member.full_name }} -
{{ frappe.utils.pretty_date(reply.creation) }}
+
{{ frappe.utils.pretty_date(reply.creation) }}
+
+
{{ _("Post") }}
+
{{ _("Dismiss") }}
+
+
+ +
+ {% if frappe.session.user == reply.owner %} + + {% endif %} +
{{ frappe.utils.md_to_html(reply.reply) }}
+
+ +
+
+
+
+ +
+
+
-
{{ frappe.utils.md_to_html(reply.reply) }}
+ diff --git a/frappe/templates/discussions/reply_section.html b/frappe/templates/discussions/reply_section.html index b269883ba0..6d219030d7 100644 --- a/frappe/templates/discussions/reply_section.html +++ b/frappe/templates/discussions/reply_section.html @@ -1,43 +1,52 @@ {% if topic %} {% set replies = frappe.get_all("Discussion Reply", {"topic": topic.name}, -["reply", "owner", "creation"], order_by="creation")%} +["reply", "owner", "creation", "name"], order_by="creation")%} {% endif %} -
- {% if not single_thread %} -
- {{ _("Back") }} -
- {% endif %} +
+ {% if not single_thread %} +
+ + + +
+ {% endif %} - {% if topic and topic.title %} -
{{ topic.title }}
- {% endif %} + {% if topic and topic.title %} +
{{ topic.title }}
+ {% endif %} +
{% for reply in replies %} + {% set index = loop.index %} {% include "frappe/templates/discussions/reply_card.html" %} - - {% if loop.index != replies | length %} -
- {% endif %} {% endfor %} {% if frappe.session.user == "Guest" or (condition is defined and not condition) %} -
- {{ _("Want to join the discussion?") }} - {% if frappe.session.user == "Guest" %} -
{{ _("Login") }}
- {% elif not condition %} -
{{ button_name }} +
+
+ +
+
+
{{ _("Want to discuss?") }}
+
{{ _("Post it here, our mentors will help you out.") }}
+
+
+ {% if frappe.session.user == "Guest" %} + + {% elif condition is defined and not condition %} + + {% endif %}
- {% endif %}
{% else %} {% include "frappe/templates/discussions/comment_box.html" %} {% endif %} -
diff --git a/frappe/templates/discussions/search.html b/frappe/templates/discussions/search.html index 800f2962fd..371c5dce9c 100644 --- a/frappe/templates/discussions/search.html +++ b/frappe/templates/discussions/search.html @@ -1,9 +1,2 @@ -
-
-
- -
-
-
+ diff --git a/frappe/templates/discussions/sidebar.html b/frappe/templates/discussions/sidebar.html index 14d38c86a5..05125f2bc3 100644 --- a/frappe/templates/discussions/sidebar.html +++ b/frappe/templates/discussions/sidebar.html @@ -1,19 +1,24 @@ -