Improve UI, add title input and forget button

This commit is contained in:
yflory 2016-11-29 17:26:31 +01:00
parent bca746bbb5
commit eaeaf4df40
5 changed files with 185 additions and 32 deletions

View File

@ -391,6 +391,9 @@ form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="checkbo
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="checkbox"]:not(.editable) ~ .cover.yes:after { form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="checkbox"]:not(.editable) ~ .cover.yes:after {
content: "✔"; content: "✔";
} }
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="checkbox"]:not(.editable) ~ .cover.uncommitted {
background: #ddd;
}
form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="checkbox"]:not(.editable) ~ .cover.mine { form.realtime table tr td.checkbox-cell div.checkbox-contain input[type="checkbox"]:not(.editable) ~ .cover.mine {
display: none; display: none;
} }

View File

@ -444,6 +444,12 @@ form.realtime {
background-color: @cp-green; background-color: @cp-green;
&:after { content: "✔"; } &:after { content: "✔"; }
} }
&.uncommitted {
background: #ddd;
}
&.mine { &.mine {
display: none; display: none;
} }

View File

@ -4,6 +4,7 @@
<meta content="text/html; charset=utf-8" http-equiv="content-type"/> <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title data-localization="poll_title">Zero Knowledge Date Picker</title> <title data-localization="poll_title">Zero Knowledge Date Picker</title>
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="/customize/main.css" /> <link rel="stylesheet" href="/customize/main.css" />
<script data-main="main" src="/bower_components/requirejs/require.js"></script> <script data-main="main" src="/bower_components/requirejs/require.js"></script>
<script> require.config({ waitSeconds: 60, }); </script> <script> require.config({ waitSeconds: 60, }); </script>
@ -43,21 +44,59 @@
border: .5px solid black; border: .5px solid black;
} }
table#table {
margin: 0px;
}
#tableContainer {
position: relative;
padding: 29px;
padding-right: 82px;
}
#tableContainer button {
height: 2rem;
}
#commit {
position: absolute;
left: 532px;
bottom: 0px;
}
#create-user {
position: absolute;
left: 0px;
top: 31px;
width: 50px;
overflow: hidden;
}
#create-option {
position: absolute;
bottom: 0px;
left: 249px;
width: 50px;
}
</style> </style>
</head> </head>
<body> <body>
<div id="toolbar"></div> <div id="toolbar"></div>
<button id="create-option">create option</button> <div id="howItWorks">
<button id="create-user">create user</button> <h1 id="mainTitle">CryptPoll</h1>
<h2 data-localization="poll_subtitle"></h2>
<p data-localization="poll_p_save"></p>
<p data-localization="poll_p_encryption"></p>
</div>
<button id="publish" style="display: none;">publish poll</button> <button id="publish" style="display: none;">publish poll</button>
<button id="commit">commit</button>
<form class="realtime"> <form class="realtime">
<br /> <br />
<input type="text" id="title"><br />
<textarea rows=5 cols=50 id="description"></textarea><br /> <textarea rows=5 cols=50 id="description"></textarea><br />
<p id="tableContainer">
<button id="create-option"><span class="fa fa-plus"></span></button>
<button id="create-user"><span class="fa fa-plus"></span></button>
<button id="commit"><span class="fa fa-check"></span></button>
</p>
</form> </form>

View File

@ -15,6 +15,10 @@ define([
//'/customize/pad.js' //'/customize/pad.js'
], function (Config, Messages, TextPatcher, Listmap, Crypto, Cryptpad, Hyperjson, Render, Toolbar) { ], function (Config, Messages, TextPatcher, Listmap, Crypto, Cryptpad, Hyperjson, Render, Toolbar) {
var $ = window.jQuery; var $ = window.jQuery;
var HIDE_INTRODUCTION_TEXT = "hide_poll_text";
var defaultName;
var APP = window.APP = { var APP = window.APP = {
Toolbar: Toolbar, Toolbar: Toolbar,
Hyperjson: Hyperjson, Hyperjson: Hyperjson,
@ -31,6 +35,10 @@ define([
return colsOrder; return colsOrder;
}; };
var isOwnColumnCommitted = function () {
return APP.proxy && APP.proxy.table.colsOrder.indexOf(APP.userid) !== -1;
};
var mergeUncommitted = function (proxy, uncommitted, commit) { var mergeUncommitted = function (proxy, uncommitted, commit) {
var newObj; var newObj;
if (commit) { if (commit) {
@ -40,7 +48,7 @@ define([
} }
// We have uncommitted data only if the user's column is not in the proxy // We have uncommitted data only if the user's column is not in the proxy
// If it is already is the proxy, nothing to merge // If it is already is the proxy, nothing to merge
if (proxy.table.colsOrder.indexOf(APP.userid) !== -1) { if (isOwnColumnCommitted()) {
return newObj; return newObj;
} }
// Merge uncommitted into the proxy // Merge uncommitted into the proxy
@ -61,6 +69,28 @@ define([
return newObj; return newObj;
}; };
var styleUncommittedColumn = function () {
var id = APP.userid;
if (isOwnColumnCommitted()) { return; }
$('[data-rt-id^="' + id + '"]').closest('td').addClass("uncommitted");
$('td.uncommitted .remove').remove();
$('td.uncommitted .cover').addClass("uncommitted");
$('.uncommitted input[type="text"]').attr("placeholder", "New column here"); //TODO
};
var updateTableButtons = function () {
if ($('.checkbox-cell').length && !isOwnColumnCommitted()) {
$('#commit').show();
$('#commit').css('width', $($('.checkbox-cell')[0]).width());
} else {
$('#commit').hide();
}
var width = $('#table').outerWidth();
if (width) {
$('#create-user').css('left', width + 30 + 'px');
}
};
/* Any time the realtime object changes, call this function */ /* Any time the realtime object changes, call this function */
var change = function (o, n, path) { var change = function (o, n, path) {
if (path && path.join) { if (path && path.join) {
@ -88,6 +118,8 @@ define([
window.setTimeout(function () { window.setTimeout(function () {
var displayedObj2 = mergeUncommitted(APP.proxy, APP.uncommitted); var displayedObj2 = mergeUncommitted(APP.proxy, APP.uncommitted);
Render.updateTable(table, displayedObj2, conf); Render.updateTable(table, displayedObj2, conf);
updateTableButtons();
styleUncommittedColumn();
}); });
}; };
@ -193,7 +225,7 @@ define([
APP.proxy.published = true; APP.proxy.published = true;
APP.$publish.hide(); APP.$publish.hide();
['textarea', '#title'].forEach(function (sel) { ['textarea'].forEach(function (sel) {
$(sel).attr('disabled', bool); $(sel).attr('disabled', bool);
}); });
}; };
@ -204,11 +236,9 @@ define([
}; };
// special UI elements // special UI elements
var $title = $('#title').attr('placeholder', Messages.poll_titleHint || 'title'); //var $title = $('#title').attr('placeholder', Messages.poll_titleHint || 'title'); TODO
var $description = $('#description').attr('placeholder', Messages.poll_descriptionHint || 'description'); var $description = $('#description').attr('placeholder', Messages.poll_descriptionHint || 'description');
var items = [$title, $description];
var ready = function (info, userid) { var ready = function (info, userid) {
console.log("READY"); console.log("READY");
console.log('userid: %s', userid); console.log('userid: %s', userid);
@ -226,7 +256,6 @@ define([
var colsOrder = sortColumns(displayedObj.table.colsOrder, userid); var colsOrder = sortColumns(displayedObj.table.colsOrder, userid);
var $table = APP.$table = $(Render.asHTML(displayedObj, null, colsOrder)); var $table = APP.$table = $(Render.asHTML(displayedObj, null, colsOrder));
var $createRow = APP.$createRow = $('#create-option').click(function () { var $createRow = APP.$createRow = $('#create-option').click(function () {
// //
@ -242,7 +271,7 @@ define([
}); });
}); });
//TODO // Commit button
var $commit = APP.$commit = $('#commit').click(function () { var $commit = APP.$commit = $('#commit').click(function () {
var uncommittedCopy = JSON.parse(JSON.stringify(APP.uncommitted)); var uncommittedCopy = JSON.parse(JSON.stringify(APP.uncommitted));
APP.uncommitted = {}; APP.uncommitted = {};
@ -251,20 +280,26 @@ define([
change(); change();
}); });
items.forEach(function ($item) { // Title
var id = $item.attr('id'); if (APP.proxy.info.defaultTitle) {
updateDefaultTitle(APP.proxy.info.defaultTitle);
} else {
APP.proxy.info.defaultTitle = defaultName
}
updateTitle(APP.proxy.info.title || defaultName);
$item.on('change keyup', function () { // Description
var val = $item.val(); $description.on('change keyup', function () {
proxy.info[id] = val; var val = $item.val();
}); proxy.info.description = val;
if (typeof(proxy.info[id]) !== 'undefined') {
$item.val(proxy.info[id]);
}
}); });
if (typeof(proxy.info.description) !== 'undefined') {
$description.val(proxy.info.descrption);
}
$('.realtime').append($table); $('#tableContainer').prepend($table);
updateTableButtons();
styleUncommittedColumn();
$table $table
.click(handleClick) .click(handleClick)
@ -272,20 +307,18 @@ define([
proxy proxy
.on('change', ['info'], function (o, n, p) { .on('change', ['info'], function (o, n, p) {
var $target = $('#' + p[1]); if (p[1] === 'title') {
var el = $target[0]; updateTitle(n);
var selects; } else if (p[1] === 'description') {
var op; var op = TextPatcher.diff(o, n);
var el = $description[0];
if (el && ['textarea', 'text'].indexOf(el.type) !== -1) { var selects = ['selectionStart', 'selectionEnd'].map(function (attr) {
op = TextPatcher.diff(o, n);
selects = ['selectionStart', 'selectionEnd'].map(function (attr) {
var before = el[attr]; var before = el[attr];
var after = TextPatcher.transformCursor(el[attr], op); var after = TextPatcher.transformCursor(el[attr], op);
return after; return after;
}); });
$target.val(n); $target.val(n);
if (op) { if (op) {
el.selectionStart = selects[0]; el.selectionStart = selects[0];
el.selectionEnd = selects[1]; el.selectionEnd = selects[1];
@ -310,6 +343,39 @@ define([
var secret = Cryptpad.getSecrets(); var secret = Cryptpad.getSecrets();
var updateTitle = function (newTitle) {
if (newTitle === document.title) { return; }
// Change the title now, and set it back to the old value if there is an error
var oldTitle = document.title;
document.title = newTitle;
Cryptpad.renamePad(newTitle, function (err, data) {
if (err) {
console.log("Couldn't set pad title");
console.error(err);
document.title = oldTitle;
return;
}
document.title = data;
APP.$bar.find('.' + Toolbar.constants.title).find('span.title').text(data);
APP.$bar.find('.' + Toolbar.constants.title).find('input').val(data);
});
};
var updateDefaultTitle = function (defaultTitle) {
defaultName = defaultTitle;
APP.$bar.find('.' + Toolbar.constants.title).find('input').attr("placeholder", defaultName);
};
var renameCb = function (err, title) {
if (err) { return; }
document.title = title;
APP.proxy.info.title = title;
};
var suggestName = function (fallback) {
return document.title || defaultName || "";
};
var create = function (info) { var create = function (info) {
var realtime = APP.realtime = info.realtime; var realtime = APP.realtime = info.realtime;
@ -324,11 +390,35 @@ define([
var config = { var config = {
userData: {}, userData: {},
readOnly: false, readOnly: false,
title: {
onRename: renameCb,
defaultName: defaultName,
suggestName: suggestName
},
common: Cryptpad common: Cryptpad
}; };
toolbar = info.realtime.toolbar = Toolbar.create(APP.$bar, info.myID, info.realtime, info.getLag, userList, config); toolbar = info.realtime.toolbar = Toolbar.create(APP.$bar, info.myID, info.realtime, info.getLag, userList, config);
var $rightside = APP.$bar.find('.' + Toolbar.constants.rightside);
/* add a forget button */
var forgetCb = function (err, title) {
if (err) { return; }
document.title = title;
};
var $forgetPad = Cryptpad.createButton('forget', true, {}, forgetCb);
$rightside.append($forgetPad);
Cryptpad.replaceHash(editHash); Cryptpad.replaceHash(editHash);
Cryptpad.getPadTitle(function (err, title) {
if (err) {
console.error(err);
console.log("Couldn't get pad title");
return;
}
updateTitle(title || defaultName);
});
}; };
var disconnect = function () { var disconnect = function () {
@ -348,6 +438,8 @@ define([
// don't initialize until the store is ready. // don't initialize until the store is ready.
Cryptpad.ready(function () { Cryptpad.ready(function () {
var parsedHash = Cryptpad.parsePadUrl(window.location.href);
defaultName = Cryptpad.getDefaultName(parsedHash);
var rt = window.rt = APP.rt = Listmap.create(config); var rt = window.rt = APP.rt = Listmap.create(config);
APP.proxy = rt.proxy; APP.proxy = rt.proxy;
rt.proxy rt.proxy
@ -363,6 +455,17 @@ define([
}); });
}) })
.on('disconnect', disconnect); .on('disconnect', disconnect);
Cryptpad.getPadAttribute(HIDE_INTRODUCTION_TEXT, function (e, value) {
if (e) { console.error(e); }
if (value === null) {
Cryptpad.setPadAttribute(HIDE_INTRODUCTION_TEXT, "1", function (e) {
if (e) { console.error(e) }
});
} else if (value === "1") {
$('#howItWorks').hide();
}
});
}); });
}); });

View File

@ -202,7 +202,8 @@ by maintaining indexes in rowsOrder and colsOrder
var result = { var result = {
'data-rt-id': col, 'data-rt-id': col,
type: 'text', type: 'text',
value: getColumnValue(obj, col) || "" value: getColumnValue(obj, col) || "",
placeholder: 'User' //TODO translate
}; };
return result; return result;
})); }));
@ -212,6 +213,7 @@ by maintaining indexes in rowsOrder and colsOrder
'data-rt-id': row, 'data-rt-id': row,
value: getRowValue(obj, row), value: getRowValue(obj, row),
type: 'text', type: 'text',
placeholder: 'Option' //TODO translate
}].concat(cols.map(function (col) { }].concat(cols.map(function (col) {
var id = [col, rows[i-1]].join('_'); var id = [col, rows[i-1]].join('_');
var val = cells[id] || false; var val = cells[id] || false;