Skip to content

Instantly share code, notes, and snippets.

@yyolk
Created December 11, 2012 08:49
Show Gist options
  • Save yyolk/4257112 to your computer and use it in GitHub Desktop.
Save yyolk/4257112 to your computer and use it in GitHub Desktop.
todoist html5 using simpleajax (via http://code.google.com/p/simpleajax/wiki/TodoistWall)
#sc_drag_area_protector div{
border-radius: 0px 0px;
margin:0;
/*max-width:100%;*/
min-width: 1px;
}
#sc_drag_area {
height:100px;
left:150px;
position: absolute;
top:100px;
width:250px;
z-index: 9999;
}
#sc_drag_container {
border: 1px solid #0000FF;
cursor: move ;
height: 100% ;
margin: 0;
overflow: hidden;
padding: 0;
position: relative ;
width: 100%;
z-index:9997;
}
#sc_drag_area_protector {
border-radius: 0px 0px;
display: block;
height:100%;
left:0;
top:0;
position: absolute;
width:100%;
z-index:8500;
margin: 0;
min-width: 1px;
overflow: hidden;
}
#sc_drag_size {
background-color: rgba(44, 44, 44, 0.5);
color:#ffffff;
font-family: arial,san-serif;
font-weight:bold;
font-size:12px;
height:18px;
min-width:65px !important;
left:12px;
line-height:18px;
position:absolute;
padding-left:4px;
padding-right:4px;
text-align:center;
top: -18px;
z-index:9998;
}
#sc_drag_cancel, #sc_drag_crop {
background-color: rgba(0, 0, 0, 0.5);
cursor:pointer;
color:#ffffff;
font-size:12px;
font-family: arial,san-serif;
font-weight:bold;
height:22px;
line-height:22px;
position:absolute ;
z-index:9998
}
#sc_drag_crop {
bottom:-25px;
text-align: center;
right:10px;
min-width: 30px !important;
padding: 0 10px;
}
#sc_drag_cancel {
bottom:-25px;
text-align: center;
right:70px;
min-width: 30px !important;
padding: 0 10px;
}
#sc_drag_shadow_top, #sc_drag_shadow_bottom, #sc_drag_shadow_left, #sc_drag_shadow_right {
background-color: #000000;
opacity: 0.5;
position: absolute;
z-index:7000;
border: 0;
}
#sc_drag_shadow_top {
left: 0;
top: 0;
}
#sc_drag_shadow_bottom {
bottom: 0;
right: 0;
}
#sc_drag_shadow_left {
bottom: 0;
left: 0;
}
#sc_drag_shadow_right {
right: 0;
top: 0;
}
#sc_drag_north_east, #sc_drag_north_west, #sc_drag_south_east, #sc_drag_south_west {
border:1px solid #FFFFFF;
background-color: #0000FF;
height: 5px;
position: absolute;
width: 5px;
z-index:9998;
}
#sc_drag_north_east {
cursor: ne-resize ;
right: -4px ;
top: -3px;
}
#sc_drag_north_west {
cursor: nw-resize ;
left: -3px ;
top: -3px;
}
#sc_drag_south_east {
bottom: -4px;
cursor: se-resize ;
right: -4px ;
}
#sc_drag_south_west {
bottom: -4px;
cursor: sw-resize ;
left: -3px ;
}
.sc_tip_save_status {
position :fixed;
border-radius: 4px 4px;
height: 30px;
line-height: 30px;
text-indent: 1em;
width: 200px;
background: #fff1a8;
color: #000000;
top:5px;
left:45%;
font-size: 12px;
}
.sc_tip_save_status a{
text-decoration: underline;
color: #2A5DB0;
}
<!DOCTYPE html>
<html manifest="todoist.manifest">
<head><title>Todoist</title>
<link rel="shortcut icon" href="http://todoist.com/favicon.ico">
<link rel="apple-touch-icon" href="todoist57.png">
<link rel="apple-touch-icon" sizes="114x114" href="todoist114.png">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<script>
function $(s) {
return document.getElementById(s);
}
var todoist = {
data: {},
countdown: 0,
projCount: 0,
afterLogin: [],
ajax: function(m, p, ssl) {
var s = document.createElement("script");
s.src = (ssl ? "https:/" : "http:/")
+ "/todoist.com/API/"
+ m
+ "?&callback=todoist.cb" + m
+ (this.token ? "&token=" + this.token : "")
+ (p || "")
+ "&.rand=" + Math.random();
document.getElementsByTagName("head")[0].appendChild(s);
},
cookie: function(n, v, remove) {
if(remove) {
document.cookie = encodeURIComponent(n) + "=; expires=Mon, 1 Jan 1980 01:01:01 GMT";
} else if(v) {
document.cookie = encodeURIComponent(n) + "=" +
encodeURIComponent(v) + "; expires=" +
new Date(new Date().getTime() + 30*24*60*60*1000).toGMTString();
} else {
var s = " " + document.cookie + ";";
var i = s.indexOf(" " + n + "=");
if(i >= 0) return decodeURIComponent(s.substring(s.indexOf("=", i) + 1, s.indexOf(";",i + 1)));
}
},
onload: function() {
this.token = this.cookie("tdtoken") || null;
var dis = this;
this.transaction(function(t) {
t.executeSql(
"SELECT * FROM projs", [],
function(t, r) {
r = r.rows;
if(r.length == 0) return dis.goOnline();
for(var i=0; i<r.length; i++) dis.data[r.item(i).id] = {name: r.item(i).name, order:r.item(i).item_order};
}
);
t.executeSql(
"SELECT * FROM tasks", [],
function(t, r) {
r = r.rows;
if(r.length == 0) return dis.goOnline();
for(var i=0; i<r.length; i++) {
var proj = dis.data[r.item(i).project_id];
if(!proj.data) proj.data = [];
var tmp = r.item(i).due_date;
proj.data.push({
id: r.item(i).id,
project_id: r.item(i).project_id,
content: r.item(i).content,
due_date: tmp ? new Date(tmp.substr(0,4), 1*tmp.substring(5,7)-1, tmp.substring(8,10), 23, 59, 59) : null,
priority: r.item(i).priority
});
}
dis.projCount = 0;
for(var i in dis.data) {
if(dis.data[i].data) dis.projCount++;
}
dis.sortView();
dis.updateView(1);
}
);
}, function(e) {
dis.goOnline();
});
},
goOnline: function() {
scrollTo(0, 0);
if(this.token) {
this.ajax("getProjects");
$("upd").style.WebkitTransform = "rotate(-180deg)";
} else {
$("loginbox").style.display = "block";
$("loginnow").value = "Login";
$("loginnow").disabled = false;
var n;
if(n = $("intro")) n.style.display = "";
if(n = $("filler")) n.style.display = "none";
}
},
login: function() {
var u = $("user").value;
var p = $("pass").value.replace(/^\s|\s$/g,"");
if(p.length > 30 && /^[0-9a-f]+$/.test(p) && confirm("Login with private token?")) {
this.cblogin({api_token: encodeURIComponent(p)});
} else {
$("loginnow").value = "Loading...";
$("loginnow").disabled = true;
u = "&email="+encodeURIComponent(u)+"&password="+encodeURIComponent(p);
this.ajax("login", u, true);
p = this;
this.loginTimeout = setTimeout(function() {p.ajax("login", u);}, 7000);
}
},
cblogin: function(r) {
$("loginnow").value = "Login";
$("loginnow").disabled = false;
clearTimeout(this.loginTimeout);
if(typeof r == "string") {
$("loginbox").style.display = "";
alert("Error: "+r);
} else {
$("loginbox").style.display = "none";
this.token = r.api_token;
this.cookie("tdtoken", this.token);
var al = this.afterLogin;
if(al.length) {
for(var i=0; i<al.length; i++) {
if(al[i]) this.ajax(al[i][0], al[i][1]);
}
} else {
this.ajax("getProjects");
$("upd").style.WebkitTransform = "rotate(-180deg)";
}
}
},
cbgetProjects: function(r) {
this.projCount = 0;
if(typeof r == "string") {
alert("Error: "+r);
this.token = null;
this.goOnline();
}
this.data = {};
for(var i=0; i<r.length; i++) {
this.data[r[i].id] = {name: r[i].name, order: r[i].item_order||0};
this.countdown++;
this.ajax("getUncompletedItems", "&js_date=1&project_id=" + r[i].id);
}
var d = this.data;
this.transaction(function(t) {
t.executeSql("DELETE FROM projs");
t.executeSql("DELETE FROM tasks");
for(var i in d) {
t.executeSql("INSERT INTO projs (id, name, item_order) VALUES (?, ?, ?)", [i, d[i].name, d[i].order]);
}
});
},
cbgetUncompletedItems: function(r) {
this.countdown--;
$("upd").style.WebkitTransform = "rotate(-"+this.countdown+"0deg)";
if(r && r.length) {
this.data[r[0].project_id].data = r;
this.projCount++;
for(var i=0; i<r.length; i++) r[i].content = r[i].content.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
this.sortView(r[0].project_id);
this.transaction(function(t) { //used by addItem
t.executeSql("DELETE FROM tasks WHERE project_id = ?", [r[0].project_id]);
});
}
if(this.countdown == 0) this.updateView();
if(r && r.length) {
var d = this.data[r[0].project_id].data;
this.transaction(function(t) {
var tmp, pad = function(i) {return i < 10 ? "0" + i : i};
for(var i=0; i<d.length; i++) {
tmp = d[i].due_date; //new Date("Sun Apr 29 23:59:59 2007")
if(tmp) tmp = tmp.getFullYear() + "-" + pad(tmp.getMonth() + 1) + "-" + pad(tmp.getDate());
t.executeSql(
"INSERT INTO tasks (id, project_id, content, due_date, priority) VALUES (?, ?, ?, ?, ?)",
[d[i].id, d[i].project_id, d[i].content, tmp, d[i].priority]
);
}
});
}
},
sortView: function(proj) {
var d = this.data, item, diff;
var now = new Date().getTime();
if(proj) {
d = {};
d[proj] = this.data[proj];
}
for(var i in d) {
if(!d[i].data) continue;
for(var j=0, x=0; j<d[i].data.length; j++) {
item = d[i].data[j];
item.due_now = 0;
if(item.due_date) {
diff = item.due_date.getTime() - now;
item.due_now = diff < 60000*60*24 ? 2 : diff < 60000*60*24*7 ? 1 : 0;
if(item.due_now == 2) {
d[i].data.splice(j, 1);
d[i].data.unshift(item);
} else if(j != x) {
d[i].data.splice(j, 1);
d[i].data.splice(x, 0, item);
}
x++;
}
}
}
},
updateView: function(silent) {
var html = [], summary = [];
var item;
var diff;
var projs = []; //sort projs
for(var i in this.data) projs.push(i);
var i = projs.length - 1;
while(i >= 0) {
var j = this.data[projs[i]].order;
if(!j || i == j - 1) {
i--;
} else {
var tmp = projs[i];
projs[i] = projs[j-1];
projs[j-1] = tmp;
}
}
for(var i=0; i<projs.length; i++) {
var proj = this.data[projs[i]];
if(!proj.data) continue;
html.push("<div class='proj'><h2><a href='javascript:if(todoist.copying){todoist.copyItem("+projs[i]+");}else{todoist.addItem("+projs[i]+");}' ondragover='if(todoist.copying&&event.preventDefault)event.preventDefault();' ondrop='todoist.copyItem("+projs[i]+");' ontouchstart='touchIsClick(this);' id='p"+projs[i]+"'>"+proj.name+"</a></h2><ul>");
for(var j=0; j<proj.data.length; j++) {
item = proj.data[j];
html.push("<li class='imp"+item.priority+(j%2?" alt eta":" eta")+item.due_now+"' id='n" + item.id+"_"+projs[i]+"' onclick='if(todoist.copying)todoist.selectItem(this);else todoist.completeItems(this);' ondragstart='todoist.copying={};todoist.selectItem(this);' ondragend='todoist.copyItem(null);'>"+item.content+"<span class='due'>"+(item.due_date?(item.due_date.getMonth()+1)+"<span class='div'>/</span>"+item.due_date.getDate():"")+"</span></li>");
if(item.due_now == 2) {
diff = item.due_date.getTime();
for(var k=0; k<summary.length; k++) {
if(diff >= summary[k].due_date.getTime()) {
summary.splice(k, 0, item);
diff = 0;
break;
}
}
if(diff) summary.push(item);
}
}
html.push("</ul></div>");
}
var width = this.projCount || 1;
if(this.projCount > 1 && summary.length) {
width++;
for(var i=0; i<summary.length; i++) {
item = summary[i];
summary[i] = "<li class='imp"+item.priority+(i%2?" alt":"")+" eta2' id='s" + item.id+"_"+item.project_id+"' onclick='if(todoist.copying)todoist.selectItem(this);else todoist.completeItems(this);'>"+item.content+"<span class='due'>"+(item.due_date?(item.due_date.getMonth()+1)+"<span class='div'>/</span>"+item.due_date.getDate():"")+"</span></li>";
}
html.unshift("<div class='proj sum'><h2><b>"+new Date().toDateString()+"</b></h2><ul>" + summary.join("") + "</ul></div>");
}
if(this.projCount == 0) html.push("<p>List is empty.</p>");
html.push("<div class='emptyprojs'>");
for(var i=0; i<projs.length; i++) {
var proj = this.data[projs[i]];
if(!proj.data) html.push("<a href='javascript:if(todoist.copying)todoist.copyItem("+projs[i]+");else todoist.addItem("+projs[i]+");'>"+proj.name+"</a> ");
}
html.push("<a href='javascript:todoist.addProject();'>[+]</a></div>");
$("main").innerHTML = html.join("");
if(!silent) {
setTimeout(function() {
document.body.className = wob ? "flash white" : "flash";
setTimeout(function() {document.body.className = wob ? "white" : "";}, 100);
}, 100);
}
},
addItem: function(id) {
if(!this.token) {
this.goOnline();
this.afterLogin.push(null);
}
var s = prompt("What to add to '"+this.data[id].name+"'?", this.lastInput || "");
var ds = s ? prompt("Remind when? d/m/yyyy", (new Date().getHours() < 18 ? "today" : "tom")) : null;
if(s) {
if(this.token) {
this.ajax("addItem", "&project_id="+id+"&priority=1&js_date=1&content="+encodeURIComponent(s)+(ds?"&date_string="+encodeURIComponent(ds):""));
} else {
this.afterLogin.push(["addItem", "&project_id="+id+"&priority=1&js_date=1&content="+encodeURIComponent(s)+(ds?"&date_string="+encodeURIComponent(ds):"")]);
}
this.lastInput = s;
}
},
cbaddItem: function(r) {
if(typeof r == "string") {
alert(r);
} else {
r.content = r.content.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
var p = this.data[r.project_id];
if(!p.data) {
p.data = [];
this.projCount++;
}
p.data.push(r);
this.sortView(r.project_id);
this.updateView();
$("n"+r.id+"_"+r.project_id).className += " fresh";
this.transaction(function(t) {
var pad = function(i) {return i < 10 ? "0" + i : i};
//new Date("Sun Apr 29 23:59:59 2007")
var tmp = !r.due_date ? null : r.due_date.getFullYear() + "-" + pad(r.due_date.getMonth() + 1) + "-" + pad(r.due_date.getDate());
t.executeSql(
"INSERT INTO tasks (id, project_id, content, due_date, priority) VALUES (?, ?, ?, ?, ?)",
[r.id, r.project_id, r.content, tmp, r.priority]
);
});
this.lastInput = "";
}
},
completeItems: function(n) {
var id = n.id.split("_"), proj = id[1];
id = id[0].substr(1);
if(confirm("Item done?")) {
if(this.token) {
this.ajax("completeItems", "&ids=%5B" + id + "%5D");
} else {
this.afterLogin.push(["completeItems", "&ids=%5B" + id + "%5D"]);
this.goOnline();
}
if((n = $("n"+id+"_"+proj))) n.parentNode.removeChild(n);
if((n = $("s"+id+"_"+proj))) n.parentNode.removeChild(n);
this.transaction(function(t) {
t.executeSql("DELETE FROM tasks WHERE id = ?", [id]);
});
var arr = this.data[proj].data;
for(var i=0; i<arr.length; i++) if(arr[i].id == id) return arr.splice(i, 1);
}
},
cbcompleteItems: function(r) {
document.body.className = wob ? "flash white" : "flash";
setTimeout(function() {document.body.className = wob ? "white" : "";}, 100);
},
updateItem: function(n_id) {
var id = n_id.split("_"), proj = id[1];
id = id[0].substr(1);
if(!this.token) {
this.goOnline();
this.afterLogin.push(null);
}
var i, arr = this.data[proj].data;
for(i=0; i<arr.length; i++) {
if(arr[i].id == id) break;
}
var dateStr = arr[i].due_date;
if(dateStr) dateStr = dateStr.getDate() + "/" + (dateStr.getMonth() + 1) + "/" + dateStr.getFullYear();
var s = prompt("Change to:", arr[i].content);
var ds = s ? prompt("Remind when? d/m/yyyy", dateStr) : "";
if(s) {
arr[i].content = s;
arr[i].date_string = ds;
arr[i].due_date = null;
var params = ["js_date=1"];
for(var j in arr[i]) {
params.push(j + "=" + encodeURIComponent(arr[i][j] || ""));
}
if(this.token) {
this.ajax("updateItem", "&" + params.join("&"));
} else {
this.afterLogin.push(["updateItem", "&" + params.join("&")]);
}
}
},
cbupdateItem: function(r) {
if(typeof r == "string") {
alert(r);
} else {
var arr = this.data[r.project_id].data;
for(var i=0; i<arr.length; i++) {
if(arr[i].id == r.id) {
arr[i] = r;
break;
}
}
this.transaction(function(t) {
var tmp = r.due_date, pad = function(i) {return i < 10 ? "0" + i : i};
if(tmp) tmp = tmp.getFullYear() + "-" + pad(tmp.getMonth() + 1) + "-" + pad(tmp.getDate());
t.executeSql(
"UPDATE tasks SET project_id=?, content=?, due_date=?, priority=? WHERE id=?",
[r.project_id, r.content, tmp, r.priority, r.id]
);
});
this.sortView(r.project_id);
this.updateView();
$("n"+r.id+"_"+r.project_id).className += " fresh";
}
},
addProject: function() {
if(!this.token) {
this.goOnline();
this.afterLogin.push(null);
}
var s = prompt("Project name?");
if(s) {
s = encodeURIComponent(s);
if(this.token) {
this.ajax("addProject", "&name="+s);
} else {
this.afterLogin.push(["addProject", "&name="+s]);
}
}
},
cbaddProject: function(r) {
if(typeof r == "string") {
alert("Error: "+r);
return;
}
var d = this.data[r.id] = {name: r.name, order: r.item_order||0};
this.transaction(function(t) {
t.executeSql("INSERT INTO projs (id, name, item_order) VALUES (?, ?, ?)", [r.id, d.name, d.order]);
});
this.updateView();
},
makeCopyable: function() {
if(this.copying) {
this.copying = null;
$("main").className = "";
} else {
this.copying = {};
$("main").className = "copy1";
}
},
selectItem: function(n) {
if(this.copying.id) {
this.copying = null;
$("main").className = "";
return;
}
var id = n.id.split("_"), proj = id[1], arr = this.data[proj].data;
id = id[0].substr(1);
for(var i=0; i<arr.length; i++) {
if(arr[i].id == id) {
this.copying = arr[i];
$("main").className = "copy2";
break;
}
}
},
copyItem: function(proj) {
var m = this.copying;
this.copying = null;
$("main").className = "";
if(!proj || m.project_id == proj) return;
var d = m.due_date || ""; //new Date("Sun Apr 29 23:59:59 2007")
var params = ["js_date=1&project_id=" + proj + (!d ? "" : "&date_string=" + d.getDate() + "%2F" + (d.getMonth()+1) + "%2F" + d.getFullYear())];
for(var i in m) {
if(m[i] && i != "project_id" && i != "id" && i != "due_date") params.push(i + "=" + encodeURIComponent(m[i] || ""));
}
if(this.token) {
this.ajax("addItem", "&" + params.join("&"));
} else {
this.goOnline();
this.afterLogin.push(["addItem", "&" + params.join("&")]);
}
},
search: function() {
var s = this.searchTerm = prompt("Search for?", this.searchTerm || "");
var arr = document.getElementsByTagName("i");
for(var i=arr.length-1; i>=0; i--) arr[i].parentNode.replaceChild(arr[i].firstChild, arr[i]);
if(s) {
s = s.toLowerCase().replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
var n, n1, n2, d, proj={}, count = 0;
for(var i in this.data) {
d = this.data[i].data;
if(!d) continue;
for(var j=0; j<d.length && count < 100; j++) {
if(d[j].content.toLowerCase().indexOf(s) >= 0) {
n = $("n" + d[j].id + "_" + d[j].project_id);
var n2 = n.removeChild(n.lastChild);
n.innerHTML = n.innerHTML.toLowerCase().split(s).join("<i>" + s + "</i>");
n.appendChild(n2);
proj[d[j].project_id] = 1;
if(count == 0 && n.getBoundingClientRect) {
n = n.getBoundingClientRect();
scrollTo(document.body.scrollLeft + n.left - 40, document.body.scrollTop + n.top - 40);
}
count++;
}
}
}
for(var j in proj) if(n = $("p" + j)) n.innerHTML = "<i>" + n.innerHTML + "</i>";
if(count == 0) alert("No matches found");
}
},
logout: function() {
this.transaction(function(t) {
t.executeSql("DELETE FROM projs");
t.executeSql("DELETE FROM tasks");
});
this.cookie("tdtoken", 0, 1);
this.cookie("tdwidths", 0, 1);
$("user").value = "";
$("pass").value = "";
this.projCount = this.token = 0;
this.data = {};
this.updateView(1);
this.goOnline();
},
transaction: function(a, b, c) {
var f = new Function("");
b = b || f;
c = c || f;
if(!this.dbms) {
this.dbms = [[a, b, c]];
var _dbms, dis = this;
try {
_dbms = window.openDatabase("todoist-dashboard", "1.0", "Tasks", 5*1024*1024);
_dbms.transaction(
function(t) {
t.executeSql("CREATE TABLE IF NOT EXISTS tasks (id INTEGER, project_id INTEGER, content TEXT, due_date DATE, priority TINYINT)");
t.executeSql("CREATE TABLE IF NOT EXISTS projs (id INTEGER, name TEXT, item_order INTEGER)");
}, function(e) {
dis.transaction = f;
for(var i=0; i<dis.dbms.length; i++) dis.dbms[i][1](e);
}, function() { //ok
for(var i=0; i<dis.dbms.length; i++) _dbms.transaction.apply(_dbms, dis.dbms[i]);
dis.dbms = _dbms;
}
);
} catch(e) {
this.transaction = f;
for(var i=0; i<this.dbms.length; i++) this.dbms[i][1](e);
}
} else if(this.dbms.transaction) {
this.dbms.transaction(a, b, c);
} else {
this.dbms.push([a, b, c]);
}
}
};
</script>
<style>
body {margin:3px; padding:1px; background:#000; color:#fff; -webkit-tap-highlight-color:rgba(255,255,255,0.2); -webkit-text-size-adjust:100%}
body,form,#foot {font:11pt Helvetica,Arial}
#foot {background:#000; color:#aaa; clear:both}
body.flash {background:#333}
.proj {float:left; width:32%; margin:1em 5px; padding:0; box-sizing:border-box; -moz-box-sizing:border-box; -webkit-box-sizing:border-box}
.proj h2 {margin:0; padding:0; font:bold 125% Helvetica,Arial}
.proj h2 a {text-decoration:none; padding:0 1em 0.3em 0.7em}
.token, .token a {color:#aaa}
a {font-size:100%; color:#fff}
.emptyprojs {font-size:100%} .emptyprojs a {color:#999; margin-right:1em; text-decoration:none}
.due {color:#bbf; font-size:90%; margin-left:6px}
.due:not(:empty) {background:rgba(255,255,255,0.15); padding:0 0.3em; border-radius:0.5em}
.white .due:not(:empty) {background:rgba(0,0,0,0.05)}
li .div {margin:0 0.1em}
.eta1, .eta2 {background:#222; border-color:#333}
.eta2 {background:#333; border-color:#444}
.white .eta1 {background:#ffc; border-color:#eeb}
.white .eta2 {background:#fdd; border-color:#ecc}
.sum h2 {padding:0 0.7em; color:#444}
.sum h2 b {font-size:70%}
.sum .eta2 {background:none; border-color:#333}
.white .sum .eta2 {border-color:#eee}
ul {border:1px solid #444}
.white ul {border-color:#ddd}
ul,li {padding:0; margin:0; list-style:none; vertical-align:middle; word-wrap:break-word}
li {padding:0.5em 0 0.5em 1.2em; border-bottom:1px solid #333; text-indent:-0.8em; color:#ccc; -moz-border-radius:0.6em; cursor:pointer; -webkit-transition:margin 0.3s; -webkit-user-drag:element}
li:last-child {border:0}
.white li {border-color:#eee}
li:hover {-webkit-user-select:none}
#main .proj ul {max-height:461px; overflow-y:auto; -webkit-overflow-scrolling:touch}
#main li:-webkit-drag {background:#000; color:#fff}
li.alt {color:#fff}
li.imp2 {color:#0c0} li.imp3 {color:#88f} li.imp4 {color:#f00}
ul>li.imp4.eta2 {background:#733; color:#fff}
@media screen and (max-width: 800px) {.proj {width:45%}}
@media screen and (max-device-width: 480px) {body,form,#foot{font-size:13pt} .proj {margin:0} .proj > ul {width:320px; border:0} #main {display:table-row} #main .proj {float:none; display:table-cell}}
.proj i {font-style:normal; background:#ff4; padding:0 0.1em; -moz-border-radius:0.3em; border-radius:0.3em; color:#000}
#foot a {padding:0.3em 0.5em; margin-top:1em}
#upd {-webkit-transition:-webkit-transform 0.5s}
.fresh {-webkit-animation:darkflash 3s 1 ease-in}
.white .fresh {-webkit-animation:lightflash 3s 1 ease-in}
.white #main li:-webkit-drag {background:#fff; color:#000}
.white .proj i {background:#cc0; color:#fff}
.white, .white #foot {background:#fff; color:#000}
.white .emptyprojs a {color:#bbb}
.white a {color:#555}
.white .due {color:#33f}
.white .sum h2 {color:#ccc}
.white li {color:#888}
.white li.alt {color:#000}
.white li.imp2 {color:#1d1} .white li.imp3 {color:#44f} .white li.imp4 {color:#f44}
.white ul>li.imp4.eta2 {background:#fcc; color:#000}
.copy1 li {margin-top:0.3em}
.copy1 .proj h2 a, .copy2 .proj h2 a {border-radius:0.3em; -webkit-transition:background-color 0.5s}
.copy1 li {background:#555}
.copy2 .proj h2 a {background:#555}
.white .copy1 li {background:#ffa}
.white .copy2 .proj h2 a {background:#ffa}
.resizeme {display:none}
#intro .proj {width:32%}
@media print {#main .proj{float:none;width:auto;-webkit-column-count:4;-webkit-column-gap:1em;-moz-column-count:4;-moz-column-gap:1em;border-bottom:1px dashed #888} #foot{display:none}}
@-webkit-keyframes darkflash {from {background:#880}}
@-webkit-keyframes lightflash {from {background:#ffb}}
.proj ::-webkit-scrollbar {width:8px; height:8px}
.proj ::-webkit-scrollbar-thumb {background-color: #666; -webkit-box-shadow: inset -1px -1px 0 #888}
.white .proj ::-webkit-scrollbar-thumb {background-color: #ccc; -webkit-box-shadow: inset 1px 1px 0 #aaa}
</style>
</head>
<body style="overflow:auto">
<form id="loginbox" style="margin:5px;padding:0;display:none" onsubmit="todoist.login();return false;">
Email:<br><input id="user" type="email" autocorrect="off" autocapitalize="off">
<br>Password: <span class="token">or <a href="http://getsatisfaction.com/todoist/topics/how_do_i_get_an_api_token" tabindex="-1">Private Token</a></span><br><input id="pass" type="password">
<br><input type="submit" id="loginnow" value="Login"> <a href="http://todoist.com">Register</a>
</form>
<noscript style="color:#f55">Please enable JavaScript.</noscript>
<div id="main"><div id="intro" style="display:none">
<div class="proj"><h2><a href="#">what is Todoist Wall?</a></h2><ul><li>an <a href="http://simpleajax.googlecode.com/svn/docs/demos/todoist.html" style="text-decoration:none">iPhone web app that syncs with your Todoist</a></li><li class="alt">can be read offline. needs connection to add</li><li>large readable text</li><li class="alt">designed for the iPhone screen</li><li>works just as good on your computer's browser</li><li class="alt">view all your todos on one large wall</li><li>get to all your todos just by sliding your finger</li></ul></div>
<div class="proj"><h2><a href="#">instructions</a></h2><ul><li>login with your todoist account</li><li class="alt">tap on an item to mark as done</li><li>tap on item and hold to edit</li><li class="alt">tap on project title to add a task</li><li>pinch to zoom</li><li class="alt">slide across to view other projects</li><li>add it to your iPhone home screen</li></ul></div>
<div class="proj"><h2><a href="#">todo karma</a></h2><ul><li>add a date only if a task has a deadline</li><li class="alt">items with deadlines appear at the top</li><li>due and overdue items appear shaded</li><li class="alt">use all lowercase to save time</li><li>create Projects according to your life. e.g., grocery, yacht, wedding</li><li class="alt">add things asap lest you forget</li></ul></div>
</div>
<div id="filler" style="margin-bottom:1000px;width:3000px;clear:both"></div>
</div>
<div id="foot">
<div id="man" style="display:none">
Todoist for iPhone -
<br>(1) click on project title to add a task
<br>(2) press and hold on task to edit
<br>(3) tap on task to delete
<br>(4) type !p4 while adding a task to mark it as important
<br>(5) add website to home screen to remove Safari buttons
<br><a href="javascript:todoist.logout();scrollTo(0,0);">logout</a>
<a href="javascript:todoist.makeCopyable();scrollTo(0,0);">duplicate task</a>
<a href="http://code.google.com/p/simpleajax/wiki/TodoistWall">wiki</a>
</div>
<div id="upd" style="display:inline-block;margin-left:-5px"><a href="javascript:;" onclick="todoist.goOnline();return false;" style="padding:2px;text-decoration:none;font-weight:bold" accesskey="u">&dArr;</a></div>
<a href="#" onclick="with($('man').style){display=display?'':'none';};return false;" style="padding:3px">?</a>
<a href="javascript:todoist.search();" accesskey="s" title="shortcut key: Alt+S">search</a>
</div>
<script>
var isTouch = ("ontouchend" in document.body);
todoist.onload();
var wob = (location.hash == "#w");
if(wob) document.body.className = "white";
var ok = 200;
</script>
<script defer="defer">
var touchTimer = function(e) {clearTimeout(touchTimer);};
document.body[isTouch ? "ontouchstart" : "onmousedown"] = function(e) {
clearTimeout(touchTimer);
e = !e ? event.srcElement : e.target || e.srcElement;
if(e && e.nodeType != 1) e = e.parentNode;
if(e && e.id && todoist.data) {
touchTimer = setTimeout("todoist.updateItem('"+e.id+"');", 900);
}
};
document.body[isTouch ? "ontouchmove" : "onmousemove"] = touchTimer;
document.body[isTouch ? "ontouchend" : "onmouseup"] = touchTimer;
document.body.ongesturestart = touchTimer;
function touchIsClick(n, s) {
n.setAttribute("ontouchstart", (s = n.href));
n.href = "javascript:void(0);";
eval(s);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment