|
|
|
@ -17,6 +17,7 @@ class Marvin {
|
|
|
|
|
password: c.syncPassword, |
|
|
|
|
pathname: "/" + c.syncDatabase |
|
|
|
|
}) |
|
|
|
|
this.credentials = credentials |
|
|
|
|
this.remote = new PouchDB(u.href) |
|
|
|
|
this.db = new PouchDB("marvin") |
|
|
|
|
this.synced = new Promise((resolve, reject) => { |
|
|
|
@ -29,6 +30,51 @@ class Marvin {
|
|
|
|
|
}) |
|
|
|
|
this.root = new Taskset(this, 'root', {}) |
|
|
|
|
} |
|
|
|
|
async api(url, data=null) { |
|
|
|
|
const response = await fetch("https://serv.amazingmarvin.com/api/" + url, { |
|
|
|
|
method: data ? "POST" : "GET", |
|
|
|
|
body: data ? JSON.stringify(data) : null, |
|
|
|
|
headers: { |
|
|
|
|
"X-API-Token": this.credentials.apiToken, |
|
|
|
|
'Content-Type': 'application/json', |
|
|
|
|
"Accept": "application/json" |
|
|
|
|
// todo: full access token
|
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
if (response.ok) { |
|
|
|
|
if (response.headers.get('content-type').startsWith("application/json")) { |
|
|
|
|
return response.json() |
|
|
|
|
} |
|
|
|
|
return response.text() |
|
|
|
|
} |
|
|
|
|
else throw [response.status, await response.text()] |
|
|
|
|
} |
|
|
|
|
async test() { |
|
|
|
|
// todo: throw?
|
|
|
|
|
return (await this.api("test", {})) == "OK" |
|
|
|
|
} |
|
|
|
|
trackedItem() { |
|
|
|
|
// todo: wrap in Task?
|
|
|
|
|
return this.api("trackedItem") |
|
|
|
|
} |
|
|
|
|
todayItems() { |
|
|
|
|
return this.api("todayItems") |
|
|
|
|
} |
|
|
|
|
dueItems() { |
|
|
|
|
return this.api("dueItems") |
|
|
|
|
} |
|
|
|
|
categories() { |
|
|
|
|
return this.api("categories") |
|
|
|
|
} |
|
|
|
|
labels() { |
|
|
|
|
return this.api("labels") |
|
|
|
|
} |
|
|
|
|
me() { |
|
|
|
|
return this.api("me") |
|
|
|
|
} |
|
|
|
|
trackInfo(taskIds) { |
|
|
|
|
return this.api("tracks", { taskIds }) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function chunk(xs, n) { |
|
|
|
|