add liveboard and update admin template
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
#header {
|
||||
height: 50px;
|
||||
background: #10284e;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#branding h1{
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
a:link,
|
||||
a:visited{
|
||||
color: #10284e;
|
||||
}
|
||||
|
||||
div.breadcrumbs {
|
||||
background: #30caa0;
|
||||
color: #10284e;
|
||||
}
|
||||
div.breadcrumbs a{
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.module h2, .module caption, .inline-group h2 {
|
||||
background: #30caa0;
|
||||
}
|
||||
|
||||
.button, input[type=submit], input[type=button], .submit-row input, a.button {
|
||||
background: #10284e;
|
||||
color: #fff;
|
||||
}
|
||||
@@ -27,3 +27,5 @@
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 894 B |
File diff suppressed because one or more lines are too long
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,124 @@
|
||||
(function() {
|
||||
/* Canvas */
|
||||
|
||||
var canvas = document.getElementById('drawCanvas');
|
||||
var ctx = canvas.getContext('2d');
|
||||
var color = document.querySelector(':checked').getAttribute('data-color');
|
||||
|
||||
canvas.width = Math.min(document.documentElement.clientWidth, window.innerWidth || 300);
|
||||
canvas.height = Math.min(document.documentElement.clientHeight, window.innerHeight || 300);
|
||||
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = '3';
|
||||
ctx.lineCap = ctx.lineJoin = 'round';
|
||||
|
||||
/* Mouse and touch events */
|
||||
|
||||
document.getElementById('colorSwatch').addEventListener('click', function() {
|
||||
color = document.querySelector(':checked').getAttribute('data-color');
|
||||
}, false);
|
||||
|
||||
var isTouchSupported = 'ontouchstart' in window;
|
||||
var isPointerSupported = navigator.pointerEnabled;
|
||||
var isMSPointerSupported = navigator.msPointerEnabled;
|
||||
|
||||
var downEvent = isTouchSupported ? 'touchstart' : (isPointerSupported ? 'pointerdown' : (isMSPointerSupported ? 'MSPointerDown' : 'mousedown'));
|
||||
var moveEvent = isTouchSupported ? 'touchmove' : (isPointerSupported ? 'pointermove' : (isMSPointerSupported ? 'MSPointerMove' : 'mousemove'));
|
||||
var upEvent = isTouchSupported ? 'touchend' : (isPointerSupported ? 'pointerup' : (isMSPointerSupported ? 'MSPointerUp' : 'mouseup'));
|
||||
|
||||
canvas.addEventListener(downEvent, startDraw, false);
|
||||
canvas.addEventListener(moveEvent, draw, false);
|
||||
canvas.addEventListener(upEvent, endDraw, false);
|
||||
|
||||
/* PubNub */
|
||||
|
||||
var channel = 'draw';
|
||||
|
||||
var pubnub = PUBNUB.init({
|
||||
publish_key : 'pub-c-150fdb3a-1221-4a4d-844a-2d200e3ec2fc',
|
||||
subscribe_key : 'sub-c-cb3013e6-32e5-11eb-9713-12bae088af96',
|
||||
leave_on_unload : true,
|
||||
ssl : document.location.protocol === "https:"
|
||||
});
|
||||
|
||||
pubnub.subscribe({
|
||||
channel: channel,
|
||||
callback: drawFromStream,
|
||||
presence: function(m){
|
||||
if(m.occupancy > 1){
|
||||
document.getElementById('unit').textContent = 'Students Online';
|
||||
}
|
||||
document.getElementById('occupancy').textContent = m.occupancy;
|
||||
var p = document.getElementById('occupancy').parentNode;
|
||||
p.classList.add('anim');
|
||||
p.addEventListener('transitionend', function(){p.classList.remove('anim');}, false);
|
||||
}
|
||||
});
|
||||
|
||||
function publish(data) {
|
||||
pubnub.publish({
|
||||
channel: channel,
|
||||
message: data
|
||||
});
|
||||
}
|
||||
|
||||
/* Draw on canvas */
|
||||
|
||||
function drawOnCanvas(color, plots) {
|
||||
ctx.strokeStyle = color;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(plots[0].x, plots[0].y);
|
||||
|
||||
for(var i=1; i<plots.length; i++) {
|
||||
ctx.lineTo(plots[i].x, plots[i].y);
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
function drawFromStream(message) {
|
||||
if(!message || message.plots.length < 1) return;
|
||||
drawOnCanvas(message.color, message.plots);
|
||||
}
|
||||
|
||||
// Get Older and Past Drawings!
|
||||
if(drawHistory) {
|
||||
pubnub.history({
|
||||
channel : channel,
|
||||
count : 50,
|
||||
callback : function(messages) {
|
||||
pubnub.each( messages[0], drawFromStream );
|
||||
}
|
||||
});
|
||||
}
|
||||
var isActive = false;
|
||||
var plots = [];
|
||||
|
||||
function draw(e) {
|
||||
e.preventDefault(); // prevent continuous touch event process e.g. scrolling!
|
||||
if(!isActive) return;
|
||||
|
||||
var x = isTouchSupported ? (e.targetTouches[0].pageX - canvas.offsetLeft) : (e.offsetX || e.layerX - canvas.offsetLeft);
|
||||
var y = isTouchSupported ? (e.targetTouches[0].pageY - canvas.offsetTop) : (e.offsetY || e.layerY - canvas.offsetTop);
|
||||
|
||||
plots.push({x: (x << 0), y: (y << 0)}); // round numbers for touch screens
|
||||
|
||||
drawOnCanvas(color, plots);
|
||||
}
|
||||
|
||||
function startDraw(e) {
|
||||
e.preventDefault();
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
function endDraw(e) {
|
||||
e.preventDefault();
|
||||
isActive = false;
|
||||
|
||||
publish({
|
||||
color: color,
|
||||
plots: plots
|
||||
});
|
||||
|
||||
plots = [];
|
||||
}
|
||||
})();
|
||||
+1
@@ -0,0 +1 @@
|
||||
!function(){function e(e){v.publish({channel:p,message:e})}function t(e,t){d.strokeStyle=e,d.beginPath(),d.moveTo(t[0].x,t[0].y);for(var n=1;n<t.length;n++)d.lineTo(t[n].x,t[n].y);d.stroke()}function n(e){!e||e.plots.length<1||t(e.color,e.plots)}function o(e){if(e.preventDefault(),y){var n=u?e.targetTouches[0].pageX-i.offsetLeft:e.offsetX||e.layerX-i.offsetLeft,o=u?e.targetTouches[0].pageY-i.offsetTop:e.offsetY||e.layerY-i.offsetTop;b.push({x:n<<0,y:o<<0}),t(r,b)}}function c(e){e.preventDefault(),y=!0}function a(t){t.preventDefault(),y=!1,e({color:r,plots:b}),b=[]}var i=document.getElementById("drawCanvas"),d=i.getContext("2d"),r=document.querySelector(":checked").getAttribute("data-color");i.width=Math.min(document.documentElement.clientWidth,window.innerWidth||300),i.height=Math.min(document.documentElement.clientHeight,window.innerHeight||300),d.strokeStyle=r,d.lineWidth="3",d.lineCap=d.lineJoin="round",document.getElementById("colorSwatch").addEventListener("click",function(){r=document.querySelector(":checked").getAttribute("data-color")},!1);var u="ontouchstart"in window,l=navigator.pointerEnabled,s=navigator.msPointerEnabled,f=u?"touchstart":l?"pointerdown":s?"MSPointerDown":"mousedown",m=u?"touchmove":l?"pointermove":s?"MSPointerMove":"mousemove",h=u?"touchend":l?"pointerup":s?"MSPointerUp":"mouseup";i.addEventListener(f,c,!1),i.addEventListener(m,o,!1),i.addEventListener(h,a,!1);var p="draw",v=PUBNUB.init({publish_key:"pub-c-156a6d5f-22bd-4a13-848d-b5b4d4b36695",subscribe_key:"sub-c-f762fb78-2724-11e4-a4df-02ee2ddab7fe",leave_on_unload:!0,ssl:"https:"===document.location.protocol});v.subscribe({channel:p,callback:n,presence:function(e){e.occupancy>1&&(document.getElementById("unit").textContent="doodlers"),document.getElementById("occupancy").textContent=e.occupancy;var t=document.getElementById("occupancy").parentNode;t.classList.add("anim"),t.addEventListener("transitionend",function(){t.classList.remove("anim")},!1)}}),drawHistory&&v.history({channel:p,count:50,callback:function(e){v.each(e[0],n)}});var y=!1,b=[]}();
|
||||
@@ -0,0 +1,17 @@
|
||||
{% extends 'admin/base.html' %}
|
||||
{% load static %}
|
||||
|
||||
{% block branding %}
|
||||
<h1 id = 'head'>
|
||||
<i class="fas fa-book-open"></i>
|
||||
<strong>Open Classroom</strong>
|
||||
</h1>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block extrastyle %}
|
||||
<!-- Custom fonts for this template-->
|
||||
<link href="{% static 'mainapp/vendor/fontawesome-free/css/all.min.css' %}" rel="stylesheet" type="text/css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
|
||||
<link rel="stylesheet" href="{% static 'admin/admin.css' %}">
|
||||
{% endblock %}
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
<!-- Favicons -->
|
||||
<link href="{% static 'landingpage/assets/img/favicon.png' %}" rel="icon">
|
||||
<link href="{% static 'landingpage/assets/img/apple-touch-icon.png' %}" rel="apple-touch-icon">
|
||||
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i|Montserrat:300,400,500,600,700" rel="stylesheet">
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
<!-- Custom Styles -->
|
||||
<link rel="stylesheet" href="{% static 'mainapp/css/styles.css' %}">
|
||||
|
||||
|
||||
<!-- Bootstrap core JavaScript-->
|
||||
<script src="{% static 'mainapp/vendor/jquery/jquery.min.js' %}" defer></script>
|
||||
<script src="{% static 'mainapp/vendor/bootstrap/js/bootstrap.bundle.min.js' %}" defer></script>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<!-- Sidebar - Brand -->
|
||||
<a class="sidebar-brand d-flex align-items-center justify-content-center" href="{% url 'classroom:home' %}">
|
||||
<div class="sidebar-brand-icon rotate-n-15">
|
||||
<i class="fas fa-laugh-wink"></i>
|
||||
<i class="fas fa-book-open"></i>
|
||||
</div>
|
||||
<div class="sidebar-brand-text mx-3"> OPEN CLASSROOM </div>
|
||||
</a>
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
{% load static %}
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
|
||||
<title>CoDoodler</title>
|
||||
<meta name="description" content="Draw">
|
||||
<meta name="author" content="Tomomi Imura @girlie_mac">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="{% static 'whiteboard/css/style.css' %}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<div>
|
||||
<h1>Open Board</h1>
|
||||
<h2>Live Openboard</h2>
|
||||
</div>
|
||||
<div class="bubble">
|
||||
<span id="occupancy">0</span>
|
||||
<span id="unit">Students Online</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section id="main">
|
||||
<canvas id="drawCanvas" width="300" height="300">Canvas is not supported on this browser!</canvas>
|
||||
|
||||
<section id="colorSwatch">
|
||||
<input type="radio" name="color" id="color01" data-color="gold" checked><label for="color01"></label>
|
||||
<input type="radio" name="color" id="color02" data-color="darkorange"> <label for="color02"></label>
|
||||
<input type="radio" name="color" id="color03" data-color="navy"> <label for="color03"></label>
|
||||
<input type="radio" name="color" id="color04" data-color="yellowgreen"> <label for="color04"></label>
|
||||
<input type="radio" name="color" id="color05" data-color="firebrick"> <label for="color05"></label>
|
||||
<input type="radio" name="color" id="color06" data-color="powderblue"> <label for="color06"></label>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script>
|
||||
// For history() demo, please view history.html.
|
||||
var drawHistory = false;
|
||||
</script>
|
||||
|
||||
<script src="http://cdn.pubnub.com/pubnub-3.14.1.min.js"></script>
|
||||
<script src="{% static 'whiteboard/js/app.js' %}"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,4 +5,5 @@ app_name = 'whiteboard'
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.whiteboard, name='whiteboard'),
|
||||
path('liveboard/', views.liveboard, name='liveboard'),
|
||||
]
|
||||
@@ -5,3 +5,8 @@ from django.contrib.auth.decorators import login_required
|
||||
def whiteboard(request):
|
||||
context = {}
|
||||
return render(request, 'whiteboard/whiteboard.html', context)
|
||||
|
||||
@login_required
|
||||
def liveboard(request):
|
||||
context = {}
|
||||
return render(request, 'whiteboard/liveboard.html', context)
|
||||
|
||||
Reference in New Issue
Block a user