diff --git a/apps/agenda/ChangeLog b/apps/agenda/ChangeLog new file mode 100644 index 000000000..56dfffa0d --- /dev/null +++ b/apps/agenda/ChangeLog @@ -0,0 +1 @@ +0.01: Basic agenda with events from GB diff --git a/apps/agenda/README.md b/apps/agenda/README.md new file mode 100644 index 000000000..5141673c0 --- /dev/null +++ b/apps/agenda/README.md @@ -0,0 +1,3 @@ +# Calendar + +Basic agenda reading the events synchronised from GadgetBridge diff --git a/apps/agenda/agenda-icon.js b/apps/agenda/agenda-icon.js new file mode 100644 index 000000000..ed6690033 --- /dev/null +++ b/apps/agenda/agenda-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwcCpMkyQC3wAIFgIRJn8JAoeQ/gRYwB0Bn57F/gCBHAgfCn8EDgdI/kSAoIR8oBkFgAFCCIysKCPM//4AKZAgR3/0Aj+Ag/ggP4gF/CPpr/Nf5r/NfYRhw4RL8IRDyEAABUJCIYC/AVI=")) \ No newline at end of file diff --git a/apps/agenda/agenda.js b/apps/agenda/agenda.js new file mode 100644 index 000000000..c7260af07 --- /dev/null +++ b/apps/agenda/agenda.js @@ -0,0 +1,102 @@ +/* CALENDAR is a list of: + {id:int, + type, + timestamp, + durationInSeconds, + title, + description, + location, + allDay: bool, + } + the file on storage has the same content but is an object indexed by id +*/ + +var FILE = "android.calendar.json" + +var fontSmall = "6x8"; +var fontMedium = g.getFonts().includes("6x15")?"6x15":"6x8:2"; +var fontBig = g.getFonts().includes("12x20")?"12x20":"6x8:2"; +var fontLarge = g.getFonts().includes("6x15")?"6x15:2":"6x8:4"; + +//FIXME maybe write the end from GB already? Not durationInSeconds here (or do while receiving?) +var cal; +try { cal = require("Storage").readJSON("android.calendar.json"); } catch (e) {} +if (!cal) //cal = {}; // first event + cal = { //FIXME test + 1: {id: 1, title:"foo", timestamp: 1653577989371, durationInSeconds: 3000, location: "somewhere"}, + 2: {id: 2, title:"last", timestamp: 1653579989371, durationInSeconds: 3000, location: "somewhere"}, + 3: {id: 3, title:"bar", timestamp: 1653578989371, durationInSeconds: 3000, location: "somewhere"} + }; + +function formatDateLong(timestamp) { + return new Date(timestamp*1000).toString(); +} +function formatDateShort(timestamp) { + return new Date(timestamp*1000).toISOString(); +} + +function showEvent(ev) { + var bodyFont = fontBig; + g.setFont(bodyFont); + var lines = []; + if (ev.title) lines = g.wrapString(ev.title, g.getWidth()-10) + var titleCnt = lines.length; + if (titleCnt) lines.push(""); // add blank line after title + lines = lines.concat( + g.wrapString(formatDateLong(ev.timestamp)+"\n", g.getWidth()-10), + g.wrapString(formatDateLong((+ev.timestamp) + (+ev.durationInSeconds))+"\n", g.getWidth()-10), + g.wrapString(ev.location, g.getWidth()-10), + ["",/*LANG*/"< Back"]); + E.showScroller({ + h : g.getFontHeight(), // height of each menu item in pixels + c : lines.length, // number of menu items + // a function to draw a menu item + draw : function(idx, r) { + // FIXME: in 2v13 onwards, clearRect(r) will work fine. There's a bug in 2v12 + g.setBgColor(idx=lines.length-2) + showEvent(ev); + }, + back : () => showList() + }); +} + +CALENDAR=Object.keys(cal) + .sort((a,b)=>cal[a].timestamp - cal[b].timestamp) + .map(k=>cal[k]); //make it an array + +function showList() { + E.showScroller({ + h : 48, + c : Math.max(CALENDAR.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) + draw : function(idx, r) {"ram" + var ev = CALENDAR[idx]; + g.setColor(g.theme.fg); + g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); + if (!ev) return; + var x = r.x+2, title = ev.title, body = formatDateShort(ev.timestamp)+ + "\n"+ev.location; + var m = ev.title+"\n"+ev.location, longBody=false; + if (title) g.setFontAlign(-1,-1).setFont(fontBig).drawString(title, x,r.y+2); + if (body) { + g.setFontAlign(-1,-1).setFont("6x8"); + var l = g.wrapString(body, r.w-(x+14)); + if (l.length>3) { + l = l.slice(0,3); + l[l.length-1]+="..."; + } + longBody = l.length>2; + g.drawString(l.join("\n"), x+10,r.y+20); + } + //if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2); + g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items + }, + select : idx => showEvent(CALENDAR[idx]), + back : () => load() + }); +} +showList(); diff --git a/apps/agenda/agenda.png b/apps/agenda/agenda.png new file mode 100644 index 000000000..ccbcce5ff Binary files /dev/null and b/apps/agenda/agenda.png differ diff --git a/apps/agenda/metadata.json b/apps/agenda/metadata.json new file mode 100644 index 000000000..2c1bdfe9c --- /dev/null +++ b/apps/agenda/metadata.json @@ -0,0 +1,16 @@ +{ + "id": "agenda", + "name": "Agenda", + "version": "1.01", + "description": "Simple agenda", + "icon": "agenda.png", + "screenshots": [{"url":"screenshot_agenda.png"}], + "tags": "agenda", + "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + {"name":"agenda.app.js","url":"agenda.js"}, + {"name":"agenda.img","url":"agenda-icon.js","evaluate":true} + ] +} diff --git a/apps/agenda/screenshot_agenda.png b/apps/agenda/screenshot_agenda.png new file mode 100644 index 000000000..7ef5986d4 Binary files /dev/null and b/apps/agenda/screenshot_agenda.png differ