realtime kanban board
parent
4561ddcdf3
commit
122a9fe068
@ -0,0 +1,243 @@
|
||||
define([
|
||||
'/bower_components/jquery/dist/jquery.min.js',
|
||||
],function () {
|
||||
var $ = window.jQuery;
|
||||
var Board = {};
|
||||
var proxy;
|
||||
|
||||
var Uid = function (prefix) {
|
||||
return function () {
|
||||
return prefix + Number(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER))
|
||||
.toString(32).replace(/\./g, '');
|
||||
};
|
||||
};
|
||||
|
||||
var removeUid = function (A, e) {
|
||||
var i = A.indexOf(e);
|
||||
if (i === -1) { return -1; }
|
||||
A.splice(i, 1);
|
||||
return i;
|
||||
};
|
||||
|
||||
var luid = Board.luid = Uid('l-'); // list-uid
|
||||
var cuid = Board.cuid = Uid('c-'); // card uid
|
||||
|
||||
var Input = Board.Input = function (opt) {
|
||||
return $('<input>', opt);
|
||||
};
|
||||
|
||||
/*
|
||||
populate the proxy with all the relevant fields
|
||||
return boolean whether you are the first user
|
||||
*/
|
||||
Board.initialize = function (_proxy) {
|
||||
proxy = _proxy;
|
||||
var first = false;
|
||||
|
||||
['listOrder'].forEach(function (k) {
|
||||
if (typeof(proxy[k]) === 'undefined') {
|
||||
first = true;
|
||||
proxy[k] = [];
|
||||
}
|
||||
});
|
||||
|
||||
['lists', 'cards'].forEach(function (k) {
|
||||
if (typeof(proxy[k]) === 'undefined') {
|
||||
proxy[k] = {};
|
||||
}
|
||||
});
|
||||
|
||||
return first;
|
||||
};
|
||||
|
||||
/*
|
||||
* a list is appended to the extant order
|
||||
*/
|
||||
var List = Board.List = function (id) {
|
||||
if (!id) {
|
||||
id = List.create();
|
||||
}
|
||||
|
||||
var $input = Input({
|
||||
type: 'text',
|
||||
placeholder: 'list title',
|
||||
})
|
||||
.addClass('list-title')
|
||||
.on('keyup change', function () {
|
||||
var val = $input.val();
|
||||
proxy.lists[id].title = val;
|
||||
});
|
||||
|
||||
var $cards = $('<div>', {
|
||||
|
||||
})
|
||||
.addClass('card-holder');
|
||||
|
||||
var $new = $('<a>', {
|
||||
|
||||
})
|
||||
.addClass('add-card')
|
||||
.text('add new card')
|
||||
.click(function () {
|
||||
// is this correct?
|
||||
$cards.append(Board.Card(id));
|
||||
});
|
||||
|
||||
var $list = $('<div>', {
|
||||
id: id,
|
||||
})
|
||||
.addClass('list-column')
|
||||
.append($input)
|
||||
.append($cards)
|
||||
.append($new);
|
||||
|
||||
return $list;
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
List.create = function () {
|
||||
var id = luid();
|
||||
proxy.listOrder.push(id);
|
||||
proxy.lists[id] = {
|
||||
title: "",
|
||||
cards: [],
|
||||
};
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
List.remove = function (id) {
|
||||
var i = removeUid(proxy.listOrder, id);
|
||||
if (i === -1) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
List.move = function () {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
List.insert = function () {
|
||||
|
||||
};
|
||||
|
||||
List.draw = function ($lists, lid) {
|
||||
if (!lid) {
|
||||
console.log("List Id not supplied");
|
||||
}
|
||||
|
||||
|
||||
var $parent = $lists.find('#' + lid);
|
||||
if (!$parent.length) {
|
||||
console.log("Creating new list");
|
||||
// doesn't exist. draw it fresh
|
||||
|
||||
var $list = Board.List(lid);
|
||||
$lists.append($list);
|
||||
|
||||
//console.log("Updating list");
|
||||
|
||||
//var $list = Board.List(lid);
|
||||
var title = proxy.lists[lid].title;
|
||||
|
||||
console.log(title);
|
||||
|
||||
$list.find('input.list-title').val(title);
|
||||
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// else update
|
||||
};
|
||||
|
||||
/*
|
||||
* UI element
|
||||
*/
|
||||
var Card = Board.Card = function (pid) {
|
||||
// pid => parent id
|
||||
|
||||
var id = Card.create(pid);
|
||||
|
||||
var $input = Input({
|
||||
placeholder: 'card description',
|
||||
})
|
||||
.addClass('card-title');
|
||||
|
||||
var $card = $('<div>', {
|
||||
|
||||
})
|
||||
.addClass('card-container')
|
||||
.append($input);
|
||||
|
||||
return $card;
|
||||
};
|
||||
|
||||
/*
|
||||
* a card is instantiated within a parent list
|
||||
* .create(parent) adds the relevant attributes to the data structure
|
||||
* and returns the created id
|
||||
*/
|
||||
Card.create = function (pid) {
|
||||
var id = cuid();
|
||||
|
||||
if (typeof(proxy.lists[pid]) === 'undefined') {
|
||||
console.error("Trying to create card for list which does not exist");
|
||||
return id;
|
||||
}
|
||||
|
||||
proxy.lists[pid].cards.push(id);
|
||||
proxy.cards[id] = {
|
||||
// TODO what goes in a card
|
||||
parent: pid,
|
||||
title: "",
|
||||
};
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
Card.move = function (uid, A, B) {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
Card.insert = function () {
|
||||
|
||||
};
|
||||
|
||||
Card.draw = function ($lists, cid) {
|
||||
if (!cid) {
|
||||
console.error("card id not supplied");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!proxy.cards[cid]) {
|
||||
console.error("no such card: ", cid);
|
||||
return;
|
||||
}
|
||||
|
||||
var card = proxy.cards[cid];
|
||||
|
||||
|
||||
};
|
||||
|
||||
var Draw = Board.Draw = function ($lists) {
|
||||
proxy.listOrder.forEach(function (luid) {
|
||||
List.draw($lists, luid);
|
||||
});
|
||||
};
|
||||
|
||||
return Board;
|
||||
});
|
@ -0,0 +1,103 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>Zero Knowledge Date Picker</title>
|
||||
<link rel="icon" type="image/png"
|
||||
href="/customize/main-favicon.png"
|
||||
data-main-favicon="/customize/main-favicon.png"
|
||||
data-alt-favicon="/customize/alt-favicon.png"
|
||||
id="favicon" />
|
||||
<link rel="stylesheet" href="/customize/main.css" />
|
||||
<script data-main="main" src="/bower_components/requirejs/require.js"></script>
|
||||
<script>
|
||||
require.config({
|
||||
waitSeconds: 60,
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
html, body {
|
||||
width: 100;
|
||||
}
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
#adduser, #addoption {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#lists {
|
||||
display: inline-block;
|
||||
border: 1px solid white;
|
||||
height: 80vh;
|
||||
}
|
||||
|
||||
#create-list {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
.list-column {
|
||||
vertical-align: top;
|
||||
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
width: 400px;
|
||||
height: 100%;
|
||||
border: 1px solid white;
|
||||
}
|
||||
/* input */
|
||||
input.list-title {
|
||||
margin: 15px;
|
||||
width: 80%;
|
||||
display: block;
|
||||
}
|
||||
.card-holder {
|
||||
border: 1px solid #ddd;
|
||||
width: 90%;
|
||||
margin: auto;
|
||||
}
|
||||
.add-card {
|
||||
background-color: green;
|
||||
display: block;
|
||||
height: 20px;
|
||||
width: 80%;
|
||||
cursor: pointer;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
border: 5px solid blue;
|
||||
|
||||
}
|
||||
|
||||
.card-container {
|
||||
display: block;
|
||||
height: 50px;
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
padding: 5px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
#board {
|
||||
margin-left: 10vw;
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!--<div id="main"> -->
|
||||
|
||||
<div id="toolbar" class="buttons">
|
||||
<sub><a href="/"></a></sub>
|
||||
</div>
|
||||
|
||||
<div id="board">
|
||||
<div id="lists"></div>
|
||||
<span id="create-list">Add List</span>
|
||||
</div>
|
||||
|
@ -0,0 +1,95 @@
|
||||
define([
|
||||
'/api/config?cb=' + Math.random().toString(16).substring(2),
|
||||
'/customize/messages.js',
|
||||
'/board/board.js',
|
||||
'/bower_components/textpatcher/TextPatcher.js',
|
||||
'/bower_components/chainpad-listmap/chainpad-listmap.js',
|
||||
'/bower_components/chainpad-crypto/crypto.js',
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/visible.js',
|
||||
'/common/notify.js',
|
||||
'/bower_components/file-saver/FileSaver.min.js',
|
||||
'/bower_components/jquery/dist/jquery.min.js',
|
||||
'/customize/pad.js'
|
||||
], function (Config, Messages, Board, TextPatcher, Listmap, Crypto, Cryptpad, Visible, Notify) {
|
||||
var $ = window.jQuery;
|
||||
var saveAs = window.saveAs;
|
||||
|
||||
Cryptpad.styleAlerts();
|
||||
console.log("Initializing your realtime session...");
|
||||
|
||||
var secret = Cryptpad.getSecrets();
|
||||
|
||||
var module = window.APP = {
|
||||
Board: Board,
|
||||
};
|
||||
|
||||
var unnotify = function () {
|
||||
if (!(module.tabNotification &&
|
||||
typeof(module.tabNotification.cancel) === 'function')) { return; }
|
||||
module.tabNotification.cancel();
|
||||
};
|
||||
|
||||
var notify = function () {
|
||||
if (!(Visible.isSupported() && !Visible.currently())) { return; }
|
||||
unnotify();
|
||||
module.tabNotification = Notify.tab(document.title, 1000, 10);
|
||||
};
|
||||
|
||||
var setEditable = function (bool) {
|
||||
|
||||
};
|
||||
|
||||
setEditable(false);
|
||||
|
||||
|
||||
var $lists = $('#lists');
|
||||
|
||||
var $addList = $('#create-list').click(function () {
|
||||
Board.List.draw($lists);
|
||||
});
|
||||
|
||||
var firstUser = function () {
|
||||
Cryptpad.log("You are the first user to visit this board");
|
||||
};
|
||||
|
||||
var whenReady = function (opt) {
|
||||
var rt = module.rt;
|
||||
var proxy = rt.proxy;
|
||||
|
||||
var first = Board.initialize(proxy);
|
||||
|
||||
//var board = module.board = Board.create(proxy);
|
||||
|
||||
Board.Draw($lists);
|
||||
|
||||
if (first) { firstUser(); }
|
||||
|
||||
};
|
||||
|
||||
var config = {
|
||||
websocketURL: Config.websocketURL,
|
||||
channel: secret.channel,
|
||||
data: {},
|
||||
crypto: Crypto.createEncryptor(secret.key),
|
||||
};
|
||||
|
||||
Cryptpad.ready(function () {
|
||||
var rt = module.rt = Listmap.create(config);
|
||||
var proxy = rt.proxy;
|
||||
proxy
|
||||
.on('create', function (info) {
|
||||
var realtime = module.realtime = info.realtime;
|
||||
window.location.hash = info.channel + secret.key;
|
||||
})
|
||||
.on('ready', function (info) {
|
||||
Cryptpad.log("Ready!");
|
||||
whenReady({
|
||||
|
||||
});
|
||||
})
|
||||
.on('disconnect', function () {
|
||||
Cryptpad.warn("Disconnected!");
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue