From 7a9039090d898202d70e37fa287cce1e657656c1 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 30 Aug 2021 12:46:08 +0530 Subject: [PATCH 1/6] fix: discussions structure --- .../__init__.py | 0 .../discussion_reply.js} | 2 +- .../discussion_reply.json} | 36 ++---- .../discussion_reply.py} | 16 +-- .../test_discussion_reply.py} | 2 +- .../discussion_thread/discussion_thread.py | 48 -------- .../__init__.py | 0 .../discussion_topic.js} | 2 +- .../discussion_topic.json} | 4 +- .../discussion_topic/discussion_topic.py | 31 ++++++ .../test_discussion_topic.py} | 2 +- .../web_template/discussions/__init__.py | 0 .../web_template/discussions/discussions.html | 1 + .../web_template/discussions/discussions.json | 17 +++ .../community/widgets/DiscussionComment.html | 94 +++++++++------- .../community/widgets/DiscussionMessage.html | 103 +++++++++--------- community/patches.txt | 2 + community/public/css/style.css | 14 +-- community/templates/message_card.html | 12 -- community/templates/reply_card.html | 14 +++ community/www/batch/learn.html | 2 +- community/www/discussions/index.html | 16 +-- 22 files changed, 201 insertions(+), 217 deletions(-) rename community/community/doctype/{discussion_message => discussion_reply}/__init__.py (100%) rename community/community/doctype/{discussion_thread/discussion_thread.js => discussion_reply/discussion_reply.js} (77%) rename community/community/doctype/{discussion_message/discussion_message.json => discussion_reply/discussion_reply.json} (54%) rename community/community/doctype/{discussion_message/discussion_message.py => discussion_reply/discussion_reply.py} (51%) rename community/community/doctype/{discussion_thread/test_discussion_thread.py => discussion_reply/test_discussion_reply.py} (69%) delete mode 100644 community/community/doctype/discussion_thread/discussion_thread.py rename community/community/doctype/{discussion_thread => discussion_topic}/__init__.py (100%) rename community/community/doctype/{discussion_message/discussion_message.js => discussion_topic/discussion_topic.js} (77%) rename community/community/doctype/{discussion_thread/discussion_thread.json => discussion_topic/discussion_topic.json} (97%) create mode 100644 community/community/doctype/discussion_topic/discussion_topic.py rename community/community/doctype/{discussion_message/test_discussion_message.py => discussion_topic/test_discussion_topic.py} (69%) create mode 100644 community/community/web_template/discussions/__init__.py create mode 100644 community/community/web_template/discussions/discussions.html create mode 100644 community/community/web_template/discussions/discussions.json delete mode 100644 community/templates/message_card.html create mode 100644 community/templates/reply_card.html diff --git a/community/community/doctype/discussion_message/__init__.py b/community/community/doctype/discussion_reply/__init__.py similarity index 100% rename from community/community/doctype/discussion_message/__init__.py rename to community/community/doctype/discussion_reply/__init__.py diff --git a/community/community/doctype/discussion_thread/discussion_thread.js b/community/community/doctype/discussion_reply/discussion_reply.js similarity index 77% rename from community/community/doctype/discussion_thread/discussion_thread.js rename to community/community/doctype/discussion_reply/discussion_reply.js index 93fdaaa4..1c72808d 100644 --- a/community/community/doctype/discussion_thread/discussion_thread.js +++ b/community/community/doctype/discussion_reply/discussion_reply.js @@ -1,7 +1,7 @@ // Copyright (c) 2021, FOSS United and contributors // For license information, please see license.txt -frappe.ui.form.on('Discussion Thread', { +frappe.ui.form.on('Discussion Reply', { // refresh: function(frm) { // } diff --git a/community/community/doctype/discussion_message/discussion_message.json b/community/community/doctype/discussion_reply/discussion_reply.json similarity index 54% rename from community/community/doctype/discussion_message/discussion_message.json rename to community/community/doctype/discussion_reply/discussion_reply.json index 4a7d653d..f8eb7632 100644 --- a/community/community/doctype/discussion_message/discussion_message.json +++ b/community/community/doctype/discussion_reply/discussion_reply.json @@ -5,49 +5,31 @@ "editable_grid": 1, "engine": "InnoDB", "field_order": [ - "thread", - "column_break_2", - "parent_message", - "section_break_4", - "message" + "topic", + "reply" ], "fields": [ { - "fieldname": "message", + "fieldname": "reply", "fieldtype": "Long Text", "in_list_view": 1, - "label": "Message" + "label": "Reply" }, { - "fieldname": "thread", + "fieldname": "topic", "fieldtype": "Link", "in_list_view": 1, "in_standard_filter": 1, - "label": "Thread", - "options": "Discussion Thread" - }, - { - "fieldname": "column_break_2", - "fieldtype": "Column Break" - }, - { - "fieldname": "parent_message", - "fieldtype": "Link", - "in_list_view": 1, - "label": "Parent Message", - "options": "Discussion Message" - }, - { - "fieldname": "section_break_4", - "fieldtype": "Section Break" + "label": "Topic", + "options": "Discussion Topic" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-08-12 15:59:04.811286", + "modified": "2021-08-27 15:06:51.362714", "modified_by": "Administrator", "module": "Community", - "name": "Discussion Message", + "name": "Discussion Reply", "owner": "Administrator", "permissions": [ { diff --git a/community/community/doctype/discussion_message/discussion_message.py b/community/community/doctype/discussion_reply/discussion_reply.py similarity index 51% rename from community/community/doctype/discussion_message/discussion_message.py rename to community/community/doctype/discussion_reply/discussion_reply.py index 3a9e672d..2ba1f1ed 100644 --- a/community/community/doctype/discussion_message/discussion_message.py +++ b/community/community/doctype/discussion_reply/discussion_reply.py @@ -3,20 +3,22 @@ import frappe from frappe.model.document import Document -from community.widgets import Widget, Widgets +from community.widgets import Widgets -class DiscussionMessage(Document): +class DiscussionReply(Document): def after_insert(self): data = { - "message": self, + "reply": self, + "topic": { + "name": self.topic + }, "widgets": Widgets() } - template = frappe.render_template("community/templates/message_card.html", data) - thread_info = frappe.db.get_value("Discussion Thread", self.thread, ["reference_doctype", "reference_docname"], as_dict=True) + template = frappe.render_template("community/templates/reply_card.html", data) + topic_info = frappe.db.get_value("Discussion Topic", self.topic, ["reference_doctype", "reference_docname", "name", "title"], as_dict=True) frappe.publish_realtime(event="publish_message", message = { - "thread": self.thread, "template": template, - "thread_info": thread_info + "topic_info": topic_info }, after_commit=True) diff --git a/community/community/doctype/discussion_thread/test_discussion_thread.py b/community/community/doctype/discussion_reply/test_discussion_reply.py similarity index 69% rename from community/community/doctype/discussion_thread/test_discussion_thread.py rename to community/community/doctype/discussion_reply/test_discussion_reply.py index b692f56e..45485242 100644 --- a/community/community/doctype/discussion_thread/test_discussion_thread.py +++ b/community/community/doctype/discussion_reply/test_discussion_reply.py @@ -4,5 +4,5 @@ # import frappe import unittest -class TestDiscussionThread(unittest.TestCase): +class TestDiscussionReply(unittest.TestCase): pass diff --git a/community/community/doctype/discussion_thread/discussion_thread.py b/community/community/doctype/discussion_thread/discussion_thread.py deleted file mode 100644 index cef7ef57..00000000 --- a/community/community/doctype/discussion_thread/discussion_thread.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (c) 2021, FOSS United and contributors -# For license information, please see license.txt - -import frappe -from frappe.model.document import Document - -class DiscussionThread(Document): - pass - -@frappe.whitelist() -def submit_discussion(doctype, docname, message, title=None, thread_name=None): - thread = [] - filters = {} - if doctype and docname: - filters = { - "reference_doctype": doctype, - "reference_docname": docname - } - - elif thread_name: - filters = { - "name": thread_name - } - - if filters: - thread = frappe.get_all("Discussion Thread",filters) - if len(thread): - thread = thread[0] - save_message(message, thread) - - else: - thread = frappe.get_doc({ - "doctype": "Discussion Thread", - "title": title, - "reference_doctype": doctype, - "reference_docname": docname - }) - thread.save(ignore_permissions=True) - save_message(message, thread) - - return thread.name - -def save_message(message, thread): - frappe.get_doc({ - "doctype": "Discussion Message", - "message": message, - "thread": thread.name - }).save(ignore_permissions=True) diff --git a/community/community/doctype/discussion_thread/__init__.py b/community/community/doctype/discussion_topic/__init__.py similarity index 100% rename from community/community/doctype/discussion_thread/__init__.py rename to community/community/doctype/discussion_topic/__init__.py diff --git a/community/community/doctype/discussion_message/discussion_message.js b/community/community/doctype/discussion_topic/discussion_topic.js similarity index 77% rename from community/community/doctype/discussion_message/discussion_message.js rename to community/community/doctype/discussion_topic/discussion_topic.js index 6044a179..2eebd44c 100644 --- a/community/community/doctype/discussion_message/discussion_message.js +++ b/community/community/doctype/discussion_topic/discussion_topic.js @@ -1,7 +1,7 @@ // Copyright (c) 2021, FOSS United and contributors // For license information, please see license.txt -frappe.ui.form.on('Discussion Message', { +frappe.ui.form.on('Discussion Topic', { // refresh: function(frm) { // } diff --git a/community/community/doctype/discussion_thread/discussion_thread.json b/community/community/doctype/discussion_topic/discussion_topic.json similarity index 97% rename from community/community/doctype/discussion_thread/discussion_thread.json rename to community/community/doctype/discussion_topic/discussion_topic.json index 5442c60b..c82eca04 100644 --- a/community/community/doctype/discussion_thread/discussion_thread.json +++ b/community/community/doctype/discussion_topic/discussion_topic.json @@ -33,7 +33,7 @@ "modified": "2021-08-11 12:29:43.564123", "modified_by": "Administrator", "module": "Community", - "name": "Discussion Thread", + "name": "Discussion Topic", "owner": "Administrator", "permissions": [ { @@ -54,4 +54,4 @@ "sort_order": "DESC", "title_field": "title", "track_changes": 1 -} \ No newline at end of file +} diff --git a/community/community/doctype/discussion_topic/discussion_topic.py b/community/community/doctype/discussion_topic/discussion_topic.py new file mode 100644 index 00000000..a340f837 --- /dev/null +++ b/community/community/doctype/discussion_topic/discussion_topic.py @@ -0,0 +1,31 @@ +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +import frappe +from frappe.model.document import Document + +class DiscussionTopic(Document): + pass + +@frappe.whitelist() +def submit_discussion(doctype, docname, reply, title, topic_name=None): + if topic_name: + save_message(reply, topic_name) + return topic_name + + topic = frappe.get_doc({ + "doctype": "Discussion Topic", + "title": title, + "reference_doctype": doctype, + "reference_docname": docname + }) + topic.save(ignore_permissions=True) + save_message(reply, topic.name) + return topic.name + +def save_message(reply, topic): + frappe.get_doc({ + "doctype": "Discussion Reply", + "reply": reply, + "topic": topic + }).save(ignore_permissions=True) diff --git a/community/community/doctype/discussion_message/test_discussion_message.py b/community/community/doctype/discussion_topic/test_discussion_topic.py similarity index 69% rename from community/community/doctype/discussion_message/test_discussion_message.py rename to community/community/doctype/discussion_topic/test_discussion_topic.py index 7d7145a8..56eaec14 100644 --- a/community/community/doctype/discussion_message/test_discussion_message.py +++ b/community/community/doctype/discussion_topic/test_discussion_topic.py @@ -4,5 +4,5 @@ # import frappe import unittest -class TestDiscussionMessage(unittest.TestCase): +class TestDiscussionTopic(unittest.TestCase): pass diff --git a/community/community/web_template/discussions/__init__.py b/community/community/web_template/discussions/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/community/web_template/discussions/discussions.html b/community/community/web_template/discussions/discussions.html new file mode 100644 index 00000000..c738992d --- /dev/null +++ b/community/community/web_template/discussions/discussions.html @@ -0,0 +1 @@ +{{ widgets.DiscussionMessage }} diff --git a/community/community/web_template/discussions/discussions.json b/community/community/web_template/discussions/discussions.json new file mode 100644 index 00000000..d87fa90d --- /dev/null +++ b/community/community/web_template/discussions/discussions.json @@ -0,0 +1,17 @@ +{ + "__islocal": true, + "__unsaved": 1, + "creation": "2021-08-30 12:42:31.550200", + "docstatus": 0, + "doctype": "Web Template", + "fields": [], + "idx": 0, + "modified": "2021-08-30 12:42:31.550200", + "modified_by": "Administrator", + "module": "Community", + "name": "Discussions", + "owner": "Administrator", + "standard": 1, + "template": "", + "type": "Section" +} \ No newline at end of file diff --git a/community/community/widgets/DiscussionComment.html b/community/community/widgets/DiscussionComment.html index d5c8e6b9..a1126de7 100644 --- a/community/community/widgets/DiscussionComment.html +++ b/community/community/widgets/DiscussionComment.html @@ -1,36 +1,49 @@ -
+ - + {% endblock %} From b3403b78ee3b8e94d32027e22249e3b3fcb6a618 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 30 Aug 2021 12:47:15 +0530 Subject: [PATCH 2/6] fix: removed global discussions page --- community/hooks.py | 1 - community/www/discussions/__init__.py | 0 community/www/discussions/discussion.html | 16 ------- community/www/discussions/discussion.py | 18 -------- community/www/discussions/index.html | 51 ----------------------- community/www/discussions/index.js | 14 ------- community/www/discussions/index.py | 17 -------- 7 files changed, 117 deletions(-) delete mode 100644 community/www/discussions/__init__.py delete mode 100644 community/www/discussions/discussion.html delete mode 100644 community/www/discussions/discussion.py delete mode 100644 community/www/discussions/index.html delete mode 100644 community/www/discussions/index.js delete mode 100644 community/www/discussions/index.py diff --git a/community/hooks.py b/community/hooks.py index 00472b15..488cbe9e 100644 --- a/community/hooks.py +++ b/community/hooks.py @@ -141,7 +141,6 @@ website_route_rules = [ {"from_route": "/courses//learn/.", "to_route": "batch/learn"}, {"from_route": "/courses//progress", "to_route": "batch/progress"}, {"from_route": "/courses//join", "to_route": "batch/join"}, - {"from_route": "/discussions/", "to_route": "discussions/discussion"}, {"from_route": "/user/", "to_route": "profiles/profile"}, ] diff --git a/community/www/discussions/__init__.py b/community/www/discussions/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/community/www/discussions/discussion.html b/community/www/discussions/discussion.html deleted file mode 100644 index afa8d8b1..00000000 --- a/community/www/discussions/discussion.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "templates/base.html" %} -{% block title %}{{ thread.title }}{% endblock %} -{% block head_include %} - -{% endblock %} - -{% block content %} -
-
- {{ widgets.BreadCrumb(thread=thread) }} -
{{ thread.title }}
- {{ widgets.DiscussionMessage(thread=thread.name) }} -
-
-{% endblock %} diff --git a/community/www/discussions/discussion.py b/community/www/discussions/discussion.py deleted file mode 100644 index 605e70c8..00000000 --- a/community/www/discussions/discussion.py +++ /dev/null @@ -1,18 +0,0 @@ -import frappe - -def get_context(context): - context.no_cache = 1 - - try: - thread_name = frappe.form_dict["discussion"] - except KeyError: - redirect_to_discussions() - - context.thread = frappe.db.get_value("Discussion Thread", thread_name, ["name", "title"], as_dict=True) - - if not len(context.thread): - redirect_to_discussions - -def redirect_to_discussions(): - frappe.local.flags.redirect_location = "/discussions" - raise frappe.Redirect diff --git a/community/www/discussions/index.html b/community/www/discussions/index.html deleted file mode 100644 index 5125a37b..00000000 --- a/community/www/discussions/index.html +++ /dev/null @@ -1,51 +0,0 @@ -{% extends "templates/base.html" %} -{% block title %}{{ 'Discussions' }}{% endblock %} -{% block head_include %} - -{% endblock %} - -{% block content %} -
-
-
- {{_('Discussions')}} -
- - Start a Discussion
-
-
- {% if threads | length %} -
- {% for thread in threads %} -
-
{{ thread.title }}
-
-
- - - - {{ thread.message_count }} - - - - {{ thread.member_count }} - - -
- -
- {% endfor %} -
- {% else %} -
- No discussions yet. -
- {% endif %} -
-
- - - - -{% endblock %} diff --git a/community/www/discussions/index.js b/community/www/discussions/index.js deleted file mode 100644 index 0cac1f1a..00000000 --- a/community/www/discussions/index.js +++ /dev/null @@ -1,14 +0,0 @@ -frappe.ready(() => { - $("#new-topic").click((e) => { - show_new_topic_modal(e); - }) -}) - -var show_new_topic_modal = (e) => { - e.preventDefault(); - if (frappe.session.user == "Guest") { - window.location.href = `/login?redirect-to=/discussions/`; - return; - } - $("#discussion-modal").modal("show"); -} diff --git a/community/www/discussions/index.py b/community/www/discussions/index.py deleted file mode 100644 index d474b2a5..00000000 --- a/community/www/discussions/index.py +++ /dev/null @@ -1,17 +0,0 @@ -import frappe - -def get_context(context): - context.threads = get_threads() - -def get_threads(): - threads = frappe.get_all("Discussion Thread", fields=["name", "title"]) - for thread in threads: - messages = frappe.get_all("Discussion Message", - { - "thread": thread.name - }, - ["owner"], - as_list=True) - thread.message_count = len(messages) - thread.member_count = len(set(messages)) - return threads From a49563e23fbc0047e8d68254f81ae404f55f1bd7 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 30 Aug 2021 18:39:00 +0530 Subject: [PATCH 3/6] fix: discussions template --- .../discussion_topic/discussion_topic.py | 4 +++ .../web_template/discussions/discussions.html | 3 +- .../community/widgets/DiscussionMessage.html | 32 ++++++++++++++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/community/community/doctype/discussion_topic/discussion_topic.py b/community/community/doctype/discussion_topic/discussion_topic.py index a340f837..4ab8558f 100644 --- a/community/community/doctype/discussion_topic/discussion_topic.py +++ b/community/community/doctype/discussion_topic/discussion_topic.py @@ -29,3 +29,7 @@ def save_message(reply, topic): "reply": reply, "topic": topic }).save(ignore_permissions=True) + +@frappe.whitelist() +def get_docname(route): + return frappe.db.get_value("Web Page", {"route": route}, ["name"]) diff --git a/community/community/web_template/discussions/discussions.html b/community/community/web_template/discussions/discussions.html index c738992d..4e4fd0bc 100644 --- a/community/community/web_template/discussions/discussions.html +++ b/community/community/web_template/discussions/discussions.html @@ -1 +1,2 @@ -{{ widgets.DiscussionMessage }} +{% set docname = frappe.db.get_value("Web Page", {"route": ""}, ["name"])%} +{{ widgets.DiscussionMessage(doctype="Web Page", docname=docname) }} diff --git a/community/community/widgets/DiscussionMessage.html b/community/community/widgets/DiscussionMessage.html index d2cc0f85..f36936c0 100644 --- a/community/community/widgets/DiscussionMessage.html +++ b/community/community/widgets/DiscussionMessage.html @@ -23,12 +23,16 @@ {% endfor %}
{% endfor %} + {% if not topics %} +

No discussions yet.

+ {% endif %} - From 9e1daf50621044bd1fc280c7ac28228c99043b56 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Tue, 31 Aug 2021 19:17:00 +0530 Subject: [PATCH 4/6] fix: reply card ui --- .../community/widgets/DiscussionMessage.html | 6 ++++-- community/public/css/style.css | 13 ++++++------ community/templates/reply_card.html | 21 +++++++++++-------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/community/community/widgets/DiscussionMessage.html b/community/community/widgets/DiscussionMessage.html index f36936c0..dfd2acf3 100644 --- a/community/community/widgets/DiscussionMessage.html +++ b/community/community/widgets/DiscussionMessage.html @@ -15,7 +15,7 @@ data-docname="{{ docname }}"> {% for topic in topics %}
-
{{ topic.title }}
+
{{ topic.title }}
{% set replies = frappe.get_all("Discussion Reply", {"topic": topic.name}, ["reply", "owner", "creation"], order_by="creation")%} {% for reply in replies %} @@ -24,7 +24,9 @@
{% endfor %} {% if not topics %} -

No discussions yet.

+ + No discussions yet. + {% endif %} diff --git a/community/lms/widgets/ChapterTeaser.html b/community/lms/widgets/ChapterTeaser.html index 81fd0e6d..8edfa580 100644 --- a/community/lms/widgets/ChapterTeaser.html +++ b/community/lms/widgets/ChapterTeaser.html @@ -64,10 +64,11 @@ }) var expand_the_first_chapter = () => { - var elements = $(".collapse"); + var elements = $(".course-outline .collapse"); elements.each((i, element) => { - if (i <= 1) { + if (i < 1) { show_section(element); + return false; } }); } diff --git a/community/public/css/style.css b/community/public/css/style.css index 5a60312b..36649075 100644 --- a/community/public/css/style.css +++ b/community/public/css/style.css @@ -438,7 +438,7 @@ input[type=checkbox] { .button { box-shadow: var(--btn-shadow); - border-radius: 8px; + border-radius: 4px; cursor: pointer; display: flex; align-items: center; @@ -1281,7 +1281,7 @@ pre { .thread-card { flex-direction: column; - padding: 1.5rem; + padding: 1rem; } textarea.form-control { @@ -1307,6 +1307,14 @@ textarea.form-control { margin-bottom: 40px; } +.discussions-parent .collapsing { + transition: height 0s; +} + +.discussion-topic-title { + color: var(--text-color); +} + .certificate-page .common-card-style { color: black; font-size: 1.25rem; diff --git a/community/public/icons/message.svg b/community/public/icons/message.svg index 09bab74d..241069d5 100644 --- a/community/public/icons/message.svg +++ b/community/public/icons/message.svg @@ -1,5 +1,3 @@ - - - - + + diff --git a/community/public/icons/small-add-black.svg b/community/public/icons/small-add-black.svg new file mode 100644 index 00000000..26801342 --- /dev/null +++ b/community/public/icons/small-add-black.svg @@ -0,0 +1,3 @@ + + + diff --git a/community/www/batch/learn.html b/community/www/batch/learn.html index 365e8bfe..49016c64 100644 --- a/community/www/batch/learn.html +++ b/community/www/batch/learn.html @@ -27,14 +27,9 @@ {% if membership %} {{ pagination(prev_url, next_url) }} {% endif %} - - {% set title = lesson.title + " - " + course.title %} - {% set condition = membership or is_instructor %} - {{ widgets.DiscussionMessage(doctype="Lesson", docname=lesson.name, - condition=condition, button_name="Start Learning", - redirect_to="/courses/" + course.name) }} + {{ Discussions() }} {% endblock %} @@ -96,7 +91,7 @@ Next - {% elif course.enable_certification %} + {% elif course.enable_certification %}
Get Certificate
@@ -106,6 +101,14 @@ {% endmacro %} +{% macro Discussions() %} +{% set title = lesson.title + " - " + course.title %} +{% set condition = membership or is_instructor %} +{{ widgets.DiscussionMessage(doctype="Lesson", docname=lesson.name, + condition=condition, button_name="Start Learning", + redirect_to="/courses/" + course.name) }} +{% endmacro %} + {%- block script %} {{ super() }} From d657525359b9d942dbccfab603c813e4dbb708b1 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Mon, 6 Sep 2021 18:59:59 +0530 Subject: [PATCH 6/6] fix: discussions redesign --- .../discussion_reply/discussion_reply.py | 11 +- community/community/widgets/CommentBox.html | 28 +++ .../community/widgets/DiscussionComment.html | 80 ------- .../community/widgets/DiscussionMessage.html | 177 ++++------------ community/overrides/user.py | 2 +- community/public/css/style.css | 83 +++++++- community/public/icons/message.svg | 4 +- community/public/icons/search.svg | 3 + community/templates/discussions/button.html | 7 + .../templates/discussions/discussions.js | 198 ++++++++++++++++++ .../templates/discussions/reply_card.html | 13 ++ .../templates/discussions/reply_section.html | 41 ++++ community/templates/discussions/search.html | 9 + community/templates/discussions/sidebar.html | 20 ++ .../templates/discussions/topic_modal.html | 15 ++ community/templates/reply_card.html | 17 -- community/www/batch/learn.html | 3 +- 17 files changed, 460 insertions(+), 251 deletions(-) create mode 100644 community/community/widgets/CommentBox.html delete mode 100644 community/community/widgets/DiscussionComment.html create mode 100644 community/public/icons/search.svg create mode 100644 community/templates/discussions/button.html create mode 100644 community/templates/discussions/discussions.js create mode 100644 community/templates/discussions/reply_card.html create mode 100644 community/templates/discussions/reply_section.html create mode 100644 community/templates/discussions/search.html create mode 100644 community/templates/discussions/sidebar.html create mode 100644 community/templates/discussions/topic_modal.html delete mode 100644 community/templates/reply_card.html diff --git a/community/community/doctype/discussion_reply/discussion_reply.py b/community/community/doctype/discussion_reply/discussion_reply.py index 2ba1f1ed..973a3a7b 100644 --- a/community/community/doctype/discussion_reply/discussion_reply.py +++ b/community/community/doctype/discussion_reply/discussion_reply.py @@ -14,11 +14,16 @@ class DiscussionReply(Document): }, "widgets": Widgets() } - template = frappe.render_template("community/templates/reply_card.html", data) - topic_info = frappe.db.get_value("Discussion Topic", self.topic, ["reference_doctype", "reference_docname", "name", "title"], as_dict=True) + template = frappe.render_template("community/templates/discussions/reply_card.html", data) + topic_info = frappe.get_all("Discussion Topic", {"name": self.topic}, ["reference_doctype", "reference_docname", "name", "title", "owner", "creation"]) + sidebar = frappe.render_template("community/templates/discussions/sidebar.html", { "topic": topic_info[0], "widgets": Widgets() }) + new_topic_template = frappe.render_template("community/templates/discussions/reply_section.html", { "topics": topic_info, "widgets": Widgets() }) + frappe.publish_realtime(event="publish_message", message = { "template": template, - "topic_info": topic_info + "topic_info": topic_info[0], + "sidebar": sidebar, + "new_topic_template": new_topic_template }, after_commit=True) diff --git a/community/community/widgets/CommentBox.html b/community/community/widgets/CommentBox.html new file mode 100644 index 00000000..04926a56 --- /dev/null +++ b/community/community/widgets/CommentBox.html @@ -0,0 +1,28 @@ +
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ + + +
diff --git a/community/community/widgets/DiscussionComment.html b/community/community/widgets/DiscussionComment.html deleted file mode 100644 index a1126de7..00000000 --- a/community/community/widgets/DiscussionComment.html +++ /dev/null @@ -1,80 +0,0 @@ - - - diff --git a/community/community/widgets/DiscussionMessage.html b/community/community/widgets/DiscussionMessage.html index b1b89ca2..e5bb3552 100644 --- a/community/community/widgets/DiscussionMessage.html +++ b/community/community/widgets/DiscussionMessage.html @@ -1,153 +1,54 @@ {% set topics = frappe.get_all("Discussion Topic", {"reference_doctype": doctype, "reference_docname": docname}, ["name", "title", "owner", "creation"]) %} -
-
- {{_('Discussions')}} - - New Topic - - -
- {{ widgets.DiscussionComment(doctype=doctype, docname=docname) }} +{% include "community/templates/discussions/topic_modal.html" %} +
+
+ {{_('Discussions')}} + {% if topics %} + {% include "community/templates/discussions/button.html" %} + {% endif %} +
+ + {% if topics %}
-
+
+ {% include "community/templates/discussions/search.html" %} {% for topic in topics %} {% set replies = frappe.get_all("Discussion Reply", {"topic": topic.name})%} - + +
+ {% include "community/templates/discussions/reply_section.html" %} +
+
+ {% else %} + +
+
+
No Discussions
+
There are no discussions for this {{ doctype | lower }}, why don't you start + one!
+ {% if frappe.session.user == "Guest" %} +
Log In
+ {% elif not condition %} +
+ {{ button_name }}
- {% if loop.index != topics | length %} -
+ {% else %} + {% include "community/templates/discussions/button.html" %} {% endif %} - {% endfor %} -
- -
- {% for topic in topics %} - {% set replies = frappe.get_all("Discussion Reply", {"topic": topic.name}, - ["reply", "owner", "creation"], order_by="creation")%} -
-
{{ topic.title }}
- {% for reply in replies %} - {% include "community/templates/reply_card.html" %} - {% endfor %} -
- {% endfor %} -
- - {% if not topics %} - - No discussions yet. - - {% endif %} -
- +{% block script %} + +{% endblock %} diff --git a/community/overrides/user.py b/community/overrides/user.py index 51ba0bad..ffce3bb5 100644 --- a/community/overrides/user.py +++ b/community/overrides/user.py @@ -58,7 +58,7 @@ class CustomUser(User): """ return frappe.get_all( 'LMS Course', { - 'owner': self.name, + 'instructor': self.name, 'is_published': True }) diff --git a/community/public/css/style.css b/community/public/css/style.css index 36649075..f066ac34 100644 --- a/community/public/css/style.css +++ b/community/public/css/style.css @@ -143,12 +143,12 @@ input[type=checkbox] { } .card-divider { - border: 1px solid #F4F5F6; + border: 1px solid #EEF0F2; margin-bottom: 1rem; } .card-divider-dark { - border: 1px solid #E2E6E9; + border: 1px solid #C8CFD5; margin-bottom: 16px; } @@ -221,6 +221,7 @@ input[type=checkbox] { padding-right: 1rem; } } + .button-links { color: #4C5A67; } @@ -1284,18 +1285,74 @@ pre { padding: 1rem; } -textarea.form-control { - height: 300px; -} - -.discussion-on-page .form-control { +.discussions-parent .form-control { background-color: #FFFFFF; font-size: inherit; color: inherit; + padding: 0.75rem 1rem; } -.discussion-on-page textarea { - height: 160px; +.discussion-on-page .comment-field { + height: 48px; + box-shadow: inset 0px 0px 4px rgba(0, 0, 0, 0.2); + border-radius: 4px; +} + +.modal .comment-field { + height: 300px; +} + +.no-discussions { + width: 250px; + margin: 0 auto; + text-align: center; +} + +.no-discussions .button { + margin: auto; +} + +.discussions-header { + margin: 2.5rem 0 1.25rem; +} + +.discussions-header .button { + float: right; +} + +.discussions-parent .search-field { + background-color: #E2E6E9; + background-image: url(/assets/community/icons/search.svg); + background-repeat: no-repeat; + text-indent: 1.5rem; + background-position: 1rem 0.7rem; + height: 36px; + font-size: 12px; + padding: 0.65rem 0.9rem; +} + +.discussions-sidebar { + background-color: #F4F5F6; + padding: 0.75rem; + border-radius: 4px; + max-height: 700px; + overflow-y: auto; +} + +#discussion-group { + max-height: 700px; + overflow-y: auto; +} + +.sidebar-topic { + padding: 0.75rem; + margin: 0.75rem 0; + cursor: pointer; +} + +.sidebar-topic[aria-expanded="true"] { + background: #FFFFFF; + border-radius: 4px; } .comment-footer { @@ -1315,6 +1372,14 @@ textarea.form-control { color: var(--text-color); } +.discussion-on-page .topic-title { + display: none; +} + +.discussions-sidebar .sidebar-parent:last-child .card-divider { + display: none; +} + .certificate-page .common-card-style { color: black; font-size: 1.25rem; diff --git a/community/public/icons/message.svg b/community/public/icons/message.svg index 241069d5..0f46b786 100644 --- a/community/public/icons/message.svg +++ b/community/public/icons/message.svg @@ -1,3 +1,3 @@ - - + + diff --git a/community/public/icons/search.svg b/community/public/icons/search.svg new file mode 100644 index 00000000..2cd7407c --- /dev/null +++ b/community/public/icons/search.svg @@ -0,0 +1,3 @@ + + + diff --git a/community/templates/discussions/button.html b/community/templates/discussions/button.html new file mode 100644 index 00000000..9148f770 --- /dev/null +++ b/community/templates/discussions/button.html @@ -0,0 +1,7 @@ +{% if frappe.session.user != "Guest" and +(condition is not defined or (condition is defined and condition )) %} + + New Discussion + + +{% endif %} diff --git a/community/templates/discussions/discussions.js b/community/templates/discussions/discussions.js new file mode 100644 index 00000000..818b6096 --- /dev/null +++ b/community/templates/discussions/discussions.js @@ -0,0 +1,198 @@ +frappe.ready(() => { + setup_socket_io(); + + set_docname_if_missing(); + + expand_first_discussion(); + + $(".search-field").keyup((e) => { + search_topic(e); + }); + + $(".reply").click((e) => { + show_new_topic_modal(e); + }); + + $("#login-from-discussion").click((e) => { + login_from_discussion(e); + }); + + $(".sidebar-topic").click((e) => { + if ($(e.currentTarget).attr("aria-expanded") == "true") { + e.stopPropagation(); + } + }); + + $(document).on("click", ".submit-discussion", (e) => { + submit_discussion(e); + }); +}) + +var show_new_topic_modal = (e) => { + e.preventDefault(); + $("#discussion-modal").modal("show"); + var topic = $(e.currentTarget).attr("data-topic"); + $(".modal-headings").text(topic ? "Reply" : "Start a Discussion"); + topic ? $(".topic-title").addClass("hide") : $(".topic-title").removeClass("hide"); + $("#submit-discussion").attr("data-topic", topic ? topic : ""); +} + +var setup_socket_io = () => { + const assets = [ + "/assets/frappe/js/lib/socket.io.min.js", + "/assets/frappe/js/frappe/socketio_client.js", + ] + + frappe.require(assets, () => { + if (window.dev_server) { + frappe.boot.socketio_port = "9000"; + } + frappe.socketio.init(9000); + frappe.socketio.socket.on("publish_message", (data) => { + publish_message(data); + }) + }) +} + +var publish_message = (data) => { + post_message_cleanup(); + + if ($(`.discussion-on-page[data-topic=${data.topic_info.name}]`).length) { + if ($(`.discussion-on-page[data-topic=${data.topic_info.name}] .card-divider-dark`).length) { + $(data.template).insertAfter(`.discussion-on-page[data-topic=${data.topic_info.name}] .card-divider-dark`); + } + else { + + $('
' + data.template).insertAfter(`.discussion-on-page[data-topic=${data.topic_info.name}] .discussion-form`); + } + } + else if ((decodeURIComponent($(".discussions-parent .course-content-parent").attr("data-doctype")) == data.topic_info.reference_doctype + && decodeURIComponent($(".discussions-parent .course-content-parent").attr("data-docname")) == data.topic_info.reference_docname)) { + $(data.sidebar).insertAfter(`.discussions-sidebar .form-group`); + $(`#discussion-group`).prepend(data.new_topic_template); + + if (data.topic_info.owner == frappe.session.user) { + $(".discussion-on-page").collapse(); + $(".sidebar-topic").first().click(); + } + + } + else { + window.location.reload(); + } + + update_reply_count(data.topic_info.name); +} + +var post_message_cleanup = () => { + $(".comment-field").val(""); + $("#discussion-modal").modal("hide"); + $("#no-discussions").addClass("hide"); +} + +var update_reply_count = (topic) => { + var reply_count = $(`[data-target='#t${topic}']`).find(".reply-count").text(); + reply_count = parseInt(reply_count) + 1; + $(`[data-target='#t${topic}']`).find(".reply-count").text(reply_count); +} + +var set_docname_if_missing = () => { + if ($("[data-docname='None']").length) { + frappe.call({ + method: "community.community.doctype.discussion_topic.discussion_topic.get_docname", + args: { + "route": window.location.href.split("/").slice(-1)[0] + }, + callback: (data) => { + $("[data-docname='None']").attr("data-docname", data.message); + } + }) + } +} + +var expand_first_discussion = () => { + $($(".discussions-parent .collapse")[0]).addClass("show"); + $($(".discussions-sidebar [data-toggle='collapse']")[0]).attr("aria-expanded", true); +} + +var search_topic = (e) => { + var input = $(e.currentTarget).val(); + + var topics = $(".discussions-parent .discussion-topic-title"); + if (input.length < 3 || input.trim() == "") { + topics.closest(".sidebar-parent").removeClass("hide"); + return + } + + topics.each((i, elem) => { + var topic_id = $(elem).parent().attr("data-target"); + + /* Check match in replies */ + var match_in_reply = false; + var replies = $(`${topic_id}`); + for (var reply of replies.find(".reply-text")) { + if (has_common_substring($(reply).text(), input)) { + match_in_reply = true; + break; + } + } + + /* Match found in title or replies, then show */ + if (has_common_substring($(elem).text(), input) || match_in_reply) { + $(elem).closest(".sidebar-parent").removeClass("hide") + } + else { + $(elem).closest(".sidebar-parent").addClass("hide"); + } + + }) +} + +var has_common_substring = (str1, str2) => { + var str1_arr = str1.toLowerCase().split(" "); + var str2_arr = str2.toLowerCase().split(" "); + + var substring_found = false; + for (var first_word of str1_arr) { + for (var second_word of str2_arr) { + if (first_word.indexOf(second_word) > -1) { + substring_found = true; + break; + } + } + } + return substring_found; +} + +var submit_discussion = (e) => { + e.preventDefault(); + e.stopImmediatePropagation(); + + var title = $(".topic-title:visible").length ? $(".topic-title:visible").val().trim() : ""; + var reply = $(".comment-field:visible").val().trim(); + + if (reply) { + var doctype = $(e.currentTarget).attr("data-doctype"); + doctype = doctype ? decodeURIComponent(doctype) : doctype; + + var docname = $(e.currentTarget).attr("data-docname"); + docname = docname ? decodeURIComponent(docname) : docname; + + frappe.call({ + method: "community.community.doctype.discussion_topic.discussion_topic.submit_discussion", + args: { + "doctype": doctype ? doctype : "", + "docname": docname ? docname : "", + "reply": reply, + "title": title, + "topic_name": $(e.currentTarget).closest(".discussion-on-page").attr("data-topic") + } + }) + + } +} + +var login_from_discussion = (e) => { + var redirect = $(e.currentTarget).attr("data-redirect") || window.location.href; + window.location.href = `/login?redirect-to=${redirect}`; +} diff --git a/community/templates/discussions/reply_card.html b/community/templates/discussions/reply_card.html new file mode 100644 index 00000000..ff60bc13 --- /dev/null +++ b/community/templates/discussions/reply_card.html @@ -0,0 +1,13 @@ +
+ {% set member = frappe.get_doc("User", reply.owner) %} +
+ {% set member = frappe.get_doc("User", reply.owner) %} + {{ widgets.Avatar(member=member, avatar_class="avatar-small")}} + + {{ member.full_name }} + +
just now
+
+
+
{{ reply.reply }}
+
diff --git a/community/templates/discussions/reply_section.html b/community/templates/discussions/reply_section.html new file mode 100644 index 00000000..9db944a4 --- /dev/null +++ b/community/templates/discussions/reply_section.html @@ -0,0 +1,41 @@ +{% for topic in topics %} +{% set replies = frappe.get_all("Discussion Reply", {"topic": topic.name}, +["reply", "owner", "creation"], order_by="creation desc")%} + + +{% if replies.insert(0, replies.pop()) %}{% endif %} + +{% if replies %} +
+
{{ topic.title }}
+ {% for reply in replies %} + + {% if loop.index == 2 %} +
+ {% endif %} + + {% include "community/templates/discussions/reply_card.html" %} + + {% if loop.index == 1 %} + + {% if frappe.session.user == "Guest" or (condition is defined and not condition) %} +
+ Want to join the discussion? + {% if frappe.session.user == "Guest" %} +
Log In
+ {% elif not condition %} +
{{ button_name }} +
+ {% endif %} +
+ {% else %} + {{ widgets.CommentBox(doctype=doctype, docname=docname) }} + {% endif %} + + {% endif %} + + {% endfor %} +
+{% endif %} +{% endfor %} diff --git a/community/templates/discussions/search.html b/community/templates/discussions/search.html new file mode 100644 index 00000000..2b4b6785 --- /dev/null +++ b/community/templates/discussions/search.html @@ -0,0 +1,9 @@ +
+
+
+ +
+
+
diff --git a/community/templates/discussions/sidebar.html b/community/templates/discussions/sidebar.html new file mode 100644 index 00000000..ea74fb08 --- /dev/null +++ b/community/templates/discussions/sidebar.html @@ -0,0 +1,20 @@ + diff --git a/community/templates/discussions/topic_modal.html b/community/templates/discussions/topic_modal.html new file mode 100644 index 00000000..98682d6f --- /dev/null +++ b/community/templates/discussions/topic_modal.html @@ -0,0 +1,15 @@ + diff --git a/community/templates/reply_card.html b/community/templates/reply_card.html deleted file mode 100644 index 4bcb5970..00000000 --- a/community/templates/reply_card.html +++ /dev/null @@ -1,17 +0,0 @@ -
- {% set member = frappe.get_doc("User", reply.owner) %} -
- {% set member = frappe.get_doc("User", reply.owner) %} - {{ widgets.Avatar(member=member, avatar_class="avatar-medium")}} -
- - {{ member.full_name }} - -
{{ frappe.utils.format_datetime(reply.creation, "hh:mm a, dd MMM YYYY") }}
-
- - Reply -
-
-
{{ reply.reply }}
-
diff --git a/community/www/batch/learn.html b/community/www/batch/learn.html index 49016c64..650e8a2c 100644 --- a/community/www/batch/learn.html +++ b/community/www/batch/learn.html @@ -102,8 +102,9 @@ {% endmacro %} {% macro Discussions() %} +{% set is_instructor = frappe.session.user == course.instructor %} {% set title = lesson.title + " - " + course.title %} -{% set condition = membership or is_instructor %} +{% set condition = is_instructor if is_instructor else membership %} {{ widgets.DiscussionMessage(doctype="Lesson", docname=lesson.name, condition=condition, button_name="Start Learning", redirect_to="/courses/" + course.name) }}