Created
December 11, 2012 08:49
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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,"&").replace(/</g,"<").replace(/>/g,">"); | |
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,"&").replace(/</g,"<").replace(/>/g,">"); | |
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,"&").replace(/</g,"<").replace(/>/g,">"); | |
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">⇓</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