diff --git a/community/hooks.py b/community/hooks.py index bc97e3a2..8868509c 100644 --- a/community/hooks.py +++ b/community/hooks.py @@ -145,6 +145,7 @@ primary_rules = [ {"from_route": "/dashboard", "to_route": ""}, {"from_route": "/add-a-new-batch", "to_route": "add-a-new-batch"}, {"from_route": "/courses///learn", "to_route": "courses/learn"}, + {"from_route": "/courses///learn/.", "to_route": "courses/learn"}, {"from_route": "/courses///schedule", "to_route": "courses/schedule"}, {"from_route": "/courses///members", "to_route": "courses/members"}, {"from_route": "/courses///discuss", "to_route": "courses/discuss"}, diff --git a/community/lms/doctype/chapter/chapter.json b/community/lms/doctype/chapter/chapter.json index f153ab38..93a1c09f 100644 --- a/community/lms/doctype/chapter/chapter.json +++ b/community/lms/doctype/chapter/chapter.json @@ -9,7 +9,8 @@ "course", "title", "description", - "locked" + "locked", + "index_" ], "fields": [ { @@ -35,6 +36,12 @@ "in_list_view": 1, "label": "Course", "options": "LMS Course" + }, + { + "default": "1", + "fieldname": "index_", + "fieldtype": "Int", + "label": "Index" } ], "index_web_pages_for_search": 1, @@ -45,7 +52,7 @@ "link_fieldname": "chapter" } ], - "modified": "2021-05-03 06:52:10.894328", + "modified": "2021-05-13 21:05:20.531890", "modified_by": "Administrator", "module": "LMS", "name": "Chapter", diff --git a/community/lms/doctype/lesson/lesson.json b/community/lms/doctype/lesson/lesson.json index 9c202d2f..2dbe6c92 100644 --- a/community/lms/doctype/lesson/lesson.json +++ b/community/lms/doctype/lesson/lesson.json @@ -9,7 +9,9 @@ "chapter", "lesson_type", "title", - "index_" + "index_", + "body", + "sections" ], "fields": [ { @@ -38,11 +40,22 @@ "fieldname": "index_", "fieldtype": "Int", "label": "Index" + }, + { + "fieldname": "body", + "fieldtype": "Markdown Editor", + "label": "Body" + }, + { + "fieldname": "sections", + "fieldtype": "Table", + "label": "Sections", + "options": "LMS Section" } ], "index_web_pages_for_search": 1, "links": [], - "modified": "2021-05-08 13:25:13.965162", + "modified": "2021-05-13 20:03:51.510605", "modified_by": "Administrator", "module": "LMS", "name": "Lesson", diff --git a/community/lms/doctype/lesson/lesson.py b/community/lms/doctype/lesson/lesson.py index 3bf002de..9d63a4b2 100644 --- a/community/lms/doctype/lesson/lesson.py +++ b/community/lms/doctype/lesson/lesson.py @@ -3,8 +3,22 @@ # For license information, please see license.txt from __future__ import unicode_literals -# import frappe +import frappe from frappe.model.document import Document +from ..lms_topic.section_parser import SectionParser class Lesson(Document): - pass + def before_save(self): + sections = SectionParser().parse(self.body or "") + self.sections = [self.make_lms_section(i, s) for i, s in enumerate(sections)] + + def get_sections(self): + return sorted(self.get('sections'), key=lambda s: s.index) + + def make_lms_section(self, index, section): + s = frappe.new_doc('LMS Section', parent_doc=self, parentfield='sections') + s.type = section.type + s.label = section.label + s.contents = section.contents + s.index = index + return s diff --git a/community/lms/doctype/lms_course/lms_course.py b/community/lms/doctype/lms_course/lms_course.py index c746bcea..56fc4001 100644 --- a/community/lms/doctype/lms_course/lms_course.py +++ b/community/lms/doctype/lms_course/lms_course.py @@ -177,3 +177,16 @@ class LMSCourse(Document): visibility="Public") return batches + def get_chapter(self, index): + return find("Chapter", course=self.name, index_=index) + + def get_lesson(self, chapter_index, lesson_index): + chapter_name = frappe.get_value( + "Chapter", + {"course": self.name, "index_": chapter_index}, + "name") + lesson_name = chapter_name and frappe.get_value( + "Lesson", + {"chapter": chapter_name, "index_": lesson_index}, + "name") + return lesson_name and frappe.get_doc("Lesson", lesson_name) diff --git a/community/lms/doctype/lms_topic/section_parser.py b/community/lms/doctype/lms_topic/section_parser.py index 6382d133..183a7c6b 100644 --- a/community/lms/doctype/lms_topic/section_parser.py +++ b/community/lms/doctype/lms_topic/section_parser.py @@ -1,4 +1,9 @@ """Utility to split the text in the topic into multiple sections. + +{{ section(type="example", id="foo") }} +circle(100, 100, 50) +{{ end }} + """ from __future__ import annotations from dataclasses import dataclass diff --git a/community/public/css/style.css b/community/public/css/style.css index d195eab5..1462ebf4 100644 --- a/community/public/css/style.css +++ b/community/public/css/style.css @@ -77,7 +77,7 @@ body { .lessons { padding-left: 20px; } -.lesson { +.lessons .lesson { margin: 5px 0px; font-weight: bold; } @@ -167,7 +167,7 @@ img.profile-photo { } .msger-inputarea { - position: fixed; + position: absolute; bottom: 0; width: 100%; display: flex; diff --git a/community/public/css/style.less b/community/public/css/style.less index e253bc1a..5bb00f30 100644 --- a/community/public/css/style.less +++ b/community/public/css/style.less @@ -235,7 +235,7 @@ section.lightgray { // LiveCode editor -.livecode-editor-large { +.livecode-editor { .CodeMirror { border: 1px solid #ddd; @@ -302,3 +302,7 @@ section.lightgray { #hero h1 { color: black !important; } + +.lesson { + margin: 20px 0px 20px 50px; +} diff --git a/community/www/courses/discuss/index.html b/community/www/courses/discuss/index.html index 6c8c124b..b4e19f86 100644 --- a/community/www/courses/discuss/index.html +++ b/community/www/courses/discuss/index.html @@ -14,10 +14,12 @@
{{ BatchHearder(course.name, member_count) }}
-
- {{ Messages(messages) }} +
+
+ {{ Messages(messages) }} +
+ {{ TextArea() }}
- {{ TextArea() }}
{% endblock %} @@ -44,4 +46,4 @@ -{% endmacro %} \ No newline at end of file +{% endmacro %} diff --git a/community/www/courses/learn/index.html b/community/www/courses/learn/index.html index a2a07f82..8145e872 100644 --- a/community/www/courses/learn/index.html +++ b/community/www/courses/learn/index.html @@ -1,13 +1,106 @@ {% extends "templates/base.html" %} {% from "www/macros/sidebar.html" import Sidebar %} -{% block title %}Learn{% endblock %} +{% from "www/macros/livecode.html" import LiveCodeEditorJS, LiveCodeEditor with context %} +{% block title %}{{ lesson.title }}{% endblock %} + {% block head_include %} - - + + + + + + + + + + + + + {% endblock %} + {% block content %} {{ Sidebar(course.name, batch.name) }} -
+
+ +

{{ lesson.title }} - {{ lesson.name }}

+ + {% for s in lesson.get_sections() %} +
+ {{ render_section(s) }} +
+ {% endfor %}
{% endblock %} + + +{% macro render_section(s) %} + {% if s.type == "text" %} + {{ render_section_text(s) }} + {% elif s.type == "example" or s.type == "code" or s.type == "exercise" %} + {{ LiveCodeEditor(s.name, s.get_latest_code_for_user(), s.type=="exercise", "2 hours ago") }} + {% else %} +
Unknown section type: {{s.type}}
+ {% endif %} +{% endmacro %} + +{% macro render_section_text(s) %} +
+
+ {{ frappe.utils.md_to_html(s.contents) }} +
+
+{% endmacro %} + +{%- block script %} + {{ super() }} + {{ LiveCodeEditorJS() }} + + + +{%- endblock %} diff --git a/community/www/courses/learn/index.py b/community/www/courses/learn/index.py index 83b3df0e..36b25048 100644 --- a/community/www/courses/learn/index.py +++ b/community/www/courses/learn/index.py @@ -6,6 +6,8 @@ def get_context(context): course_name = frappe.form_dict["course"] batch_name = frappe.form_dict["batch"] + chapter_index = frappe.form_dict.get("chapter") + lesson_index = frappe.form_dict.get("lesson") course = Course.find(course_name) if not course: @@ -17,5 +19,16 @@ def get_context(context): frappe.local.flags.redirect_location = "/courses/" + course_name raise frappe.Redirect + if not chapter_index or not lesson_index: + frappe.local.flags.redirect_location = f"/courses/{course_name}/{batch_name}/learn/1.1" + raise frappe.Redirect + context.course = course context.batch = batch + context.lesson = course.get_lesson(chapter_index, lesson_index) + context.lesson_index = lesson_index + context.chapter_index = chapter_index + context.livecode_url = get_livecode_url() + +def get_livecode_url(): + return frappe.db.get_single_value("LMS Settings", "livecode_url") diff --git a/community/www/macros/livecode.html b/community/www/macros/livecode.html index bb8b6993..de553e4d 100644 --- a/community/www/macros/livecode.html +++ b/community/www/macros/livecode.html @@ -24,29 +24,36 @@
{% endmacro %} -{% macro LiveCodeEditor(name, code) %} -
+{% macro LiveCodeEditor(name, code, is_exercise, last_submitted) %} +
-
-
- -
- - Reset - Clear +
+
+ + + {% if is_exercise %} + + {% if last_submitted %} + Last submitted {{last_submitted}} + {% endif %} + {% endif %}
-
-
-
- -

+  
+
+
+
+
+ +
+
+
+ +

       
- {% endmacro %}