Merge branch 'main' of https://github.com/frappe/community into main

This commit is contained in:
pateljannat
2021-03-12 12:22:19 +05:30
15 changed files with 546 additions and 94 deletions

View File

@@ -1,4 +1,5 @@
{% extends "templates/base.html" %}
{% from "www/macros/livecode.html" import LiveCodeEditor with context %}
{% block title %}{{topic.title}} ({{course.title}}){% endblock %}
{% block head_include %}
<meta name="description" content="Topic {{topic.title}} of the course {{course.title}}" />
@@ -7,6 +8,7 @@
</style>
<link rel="stylesheet" href="{{ livecode_url }}/static/codemirror/lib/codemirror.css">
<link rel="stylesheet" href="/assets/css/lms.css">
<script src="{{ livecode_url }}/static/codemirror/lib/codemirror.js"></script>
<script src="{{ livecode_url }}/static/codemirror/mode/python/python.js"></script>
@@ -42,7 +44,7 @@
{% if s.type == "text" %}
{{ render_section_text(s) }}
{% elif s.type == "code" %}
{{ render_section_code(s) }}
{{ LiveCodeEditor(s.name, s.code) }}
{% else %}
<div>Unknown section type: {{s.type}}</div>
{% endif %}
@@ -52,28 +54,6 @@
{{ s.contents | markdown }}
{% endmacro %}
{% macro render_section_code(s) %}
<div class="canvas-editor row no-gutters" id="editor-{{s.name}}">
<div class="col-sm">
<div class="heading">
<button class="run">Run</button>
<h2>Editor</h2>
</div>
<textarea class="code">{{s.code}}</textarea>
</div>
<div class="col-sm">
<div class="heading">
<h2>Output</h2>
</div>
<div class="canvas-wrapper">
<canvas class="canvas" width="300" height="300">Dashed box</canvas>
<pre class="output"></pre>
</div>
</pre>
</div>
</div>
{% endmacro %}
{%- block script %}
{{ super() }}
<script type="text/javascript" src="{{ livecode_url }}/static/livecode.js"></script>
@@ -89,73 +69,3 @@
})
</script>
{%- endblock %}
{%- block style %}
{{ super() }}
<style type="text/css">
.canvas-wrapper {
position: relative;
padding: 10px;
}
.canvas-editor canvas {
position: relative;
z-index: 0;
border: 1px solid #ddd;
height: 300px;
width: 300px;
}
.canvas-wrapper .output {
position: absolute;
z-index: 1;
width: 100%;
left: 0px;
top: 0px;
background-color: rgba(255, 255, 255, 0);
margin: 15px;
}
.canvas-editor .code {
width: 100%;
padding: 5px;
min-height: 330px;
resize: none;
}
.canvas-editor .output {
padding: 5px;
}
.heading {
background: #eee;
padding: 10px;
clear: both;
color: #212529;
border: 1px solid #ddd;
}
.canvas-editor h2 {
font-size: 1.2em;
text-transform: uppercase;
margin: 0px;
font-weight: normal;
}
.canvas-editor .run {
float: right;
}
.canvas-editor .col-sm {
border: 1px solid #ddd;
}
/* .canvas-editor canvas {
float: left;
border: 1px solid #ddd;
padding: 5px;
margin: 10px;
} */
</style>
{%- endblock %}

View File

@@ -0,0 +1,40 @@
{% macro LiveCodeEditor(name, code) %}
<div class="canvas-editor row no-gutters" id="editor-{{name}}">
<div class="col-sm">
<div class="heading">
<button class="run">Run</button>
<h2>Editor</h2>
</div>
<textarea class="code">{{code}}</textarea>
</div>
<div class="col-sm">
<div class="heading">
<h2>Output</h2>
</div>
<div class="canvas-wrapper">
<canvas class="canvas" width="300" height="300"></canvas>
<pre class="output"></pre>
</div>
</div>
</div>
{% endmacro %}
{% macro LiveCodeEditorJS(name, code) %}
<script type="text/javascript" src="{{ livecode_url }}/static/livecode.js"></script>
<script type="text/javascript">
var livecodeEditors = [];
$(function() {
$(".canvas-editor").each((i, e) => {
var editor = new LiveCodeEditor(e, {
runtime: "python-canvas",
base_url: "{{ livecode_url }}",
codemirror: true
})
livecodeEditors.push(editor);
})
})
</script>
{% endmacro %}

View File

@@ -0,0 +1,47 @@
{% extends "templates/base.html" %}
{% from "www/macros/livecode.html" import LiveCodeEditor, LiveCodeEditorJS %}
{% block title %}Sketches{% endblock %}
{% block head_include %}
<meta name="description" content="Sketches" />
<meta name="keywords" content="sketches" />
<link rel="stylesheet" href="/assets/css/lms.css">
{% endblock %}
{% block content %}
<section class="top-section" style="padding: 1rem 0rem;">
<div class='container pb-5'>
<h1>Recent Sketches</h1>
<a href="/sketches/sketch?sketch=new">Create a New Sketch</a>
</div>
<div class='container'>
<div class="row row-cols-1 row-cols-xl-5 row-cols-lg-4 row-cols-md-3 row-cols-sm-2 ">
{% for sketch in sketches %}
<div class="col mb-4">
<div class="card" style="width: 200px;">
<div class="card-img-top">
<a href="/sketches/sketch?sketch={{sketch.name}}">
{{ sketch.to_svg() }}
</a>
</div>
<div class="card-footer">
By {{sketch.get_owner_name()}}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</section>
{% endblock %}
{% block style %}
{{super()}}
<style type="text/css">
svg {
width: 200px;
height: 200px;
}
</style>
{% endblock %}

View File

@@ -0,0 +1,7 @@
import frappe
from ...lms.doctype.lms_sketch.lms_sketch import get_recent_sketches
def get_context(context):
context.no_cache = 1
context.sketches = get_recent_sketches()

View File

@@ -0,0 +1,109 @@
{% extends "templates/base.html" %}
{% from "www/macros/livecode.html" import LiveCodeEditor, LiveCodeEditorJS with context %}
{% block title %}{{sketch.title}}{% endblock %}
{% block head_include %}
<meta name="description" content="Sketch {{sketch.title}}" />
<meta name="keywords" content="sketch {{sketch.title}}" />
<style>
</style>
<link rel="stylesheet" href="{{ livecode_url }}/static/codemirror/lib/codemirror.css">
<link rel="stylesheet" href="/assets/css/lms.css">
<script src="{{ livecode_url }}/static/codemirror/lib/codemirror.js"></script>
<script src="{{ livecode_url }}/static/codemirror/mode/python/python.js"></script>
<script src="{{ livecode_url }}/static/codemirror/keymap/sublime.js"></script>
<script src="{{ livecode_url }}/static/codemirror/addon/edit/matchbrackets.js"></script>
<script src="{{ livecode_url }}/static/codemirror/addon/comment/comment.js"></script>
{% endblock %}
{% block content %}
<section class="top-section" style="padding: 1rem 0rem;">
<div class='container pb-5'>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item" aria-current="page"><a href="/sketches">Sketches</a></li>
</ol>
</nav>
<div class="sketch-header">
{% if editable %}
<input type="button" class="pull-right" id="sketch-save" value="Save"/>
<h1 class="sketch-title">
<input type="text" name="title" id="sketch-title" value="{{ sketch.title }}" />
</h1>
{% else %}
<h1 class="sketch-title">{{sketch.title}}</h1>
{% endif %}
<div class="sketch-owner-wrapper">By <span class="sketch-owner">{{sketch.get_owner_name()}}</span></div>
</div>
{% if sketch.is_new() and not editable %}
<div class="alert alert-warning">
Please login to save this sketch.
</div>
{% endif %}
<div class="sketch-editor">
{{LiveCodeEditor(sketch.name, sketch.code) }}
</div>
</section>
{% endblock %}
{%- block script %}
{{ super() }}
{{ LiveCodeEditorJS() }}
<script type="text/javascript">
var sketch_name = {{ sketch.name | tojson }};
function saveSketch() {
var title = $("#sketch-title").val()
var code = livecodeEditors[0].codemirror.doc.getValue()
frappe.call('community.lms.doctype.lms_sketch.lms_sketch.save_sketch', {
name: sketch_name,
title: title,
code: code
})
.then(r => {
var msg = r.message;
if (!msg.ok) {
var error = msg.error || "Save failed."
frappe.msgprint({
"title": "Error",
"indicator": "red",
"message": error
});
}
else if (msg.status == "created") {
var path = "/sketches/sketch?sketch=" + msg.name;
var url = window.location.protocol + "//" + window.location.host + path
window.history.pushState({path: url}, '', url);
sketch_name = name;
frappe.msgprint({
"title": "Notification",
"indicator": "green",
"message": "New sketch has been saved!"
});
}
else if (msg.status == "updated") {
frappe.msgprint({
"title": "Notification",
"indicator": "green",
"message": "The sketch has been saved!"
});
}
})
}
$(function() {
$("#sketch-save").click(function() {
saveSketch();
});
})
</script>
{%- endblock %}

View File

@@ -0,0 +1,41 @@
import frappe
def get_context(context):
context.no_cache = 1
course_name = get_queryparam("sketch", '/sketches')
context.sketch = get_sketch(course_name)
context.livecode_url = get_livecode_url()
context.editable = is_editable(context.sketch, frappe.session.user)
def is_editable(sketch, user):
if sketch.is_new():
# new sketches can be editable by any logged in user
return user != "Guest"
else:
# existing sketches are editable by the owner
return sketch.owner == user
def get_livecode_url():
doc = frappe.get_doc("LMS Settings")
return doc.livecode_url
def get_queryparam(name, redirect_when_not_found):
try:
return frappe.form_dict[name]
except KeyError:
frappe.local.flags.redirect_location = redirect_when_not_found
raise frappe.Redirect
def get_sketch(name):
if name == 'new':
sketch = frappe.new_doc('LMS Sketch')
sketch.name = "new"
sketch.title = "New Sketch"
sketch.code = "circle(100, 100, 50)"
return sketch
try:
return frappe.get_doc('LMS Sketch', name)
except frappe.exceptions.DoesNotExistError:
raise frappe.NotFound