mirror of https://github.com/espruino/BangleApps
417 lines
14 KiB
HTML
417 lines
14 KiB
HTML
<html>
|
|
<head>
|
|
<style>
|
|
body {
|
|
padding: 0;
|
|
margin: 0;
|
|
}
|
|
html, body, #map {
|
|
height: 100%;
|
|
width: 100%;
|
|
}
|
|
#controls {
|
|
padding: 10px;
|
|
margin: 10px;
|
|
border: 1px solid black;
|
|
position:absolute;
|
|
right:0px;bottom:0px;
|
|
background-color: rgb(255, 255, 255);
|
|
z-index: 100;
|
|
}
|
|
</style>
|
|
<link href='fullcalendar/main.css' rel='stylesheet' />
|
|
<link rel="stylesheet" href="../../css/spectre.min.css">
|
|
</head>
|
|
<body>
|
|
<div>
|
|
<p>Create your events on the week shown. Keep in note that your events repeat weekly.</p>
|
|
<p>One you have created your events, Click <button id="upload" class="btn btn-primary">Upload</button>.</p>
|
|
<p>All day events are not supported. A feature that lets you get the calendar from your watch will be added in a future update.</p>
|
|
</div>
|
|
|
|
<script src='fullcalendar/main.js'></script>
|
|
<script src="../../core/lib/customize.js"></script>
|
|
|
|
<script>
|
|
var calendar;
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var calendarEl = document.getElementById('calendar');
|
|
calendar = new FullCalendar.Calendar(calendarEl, {
|
|
initialView: 'timeGridWeek',
|
|
headerToolbar: {
|
|
left: '',
|
|
center: 'title',
|
|
right: 'timeGridWeek,listWeek'
|
|
},
|
|
navLinks: true, // can click day/week names to navigate views
|
|
editable: true,
|
|
selectable: true,
|
|
selectMirror: true,
|
|
nowIndicator: true,
|
|
editable: true,
|
|
height: 600,
|
|
initialDate: '2018-06-03', // will be parsed as local
|
|
select: function(arg) {
|
|
var title = prompt('Event Title:');
|
|
if (title) {
|
|
calendar.addEvent({
|
|
title: title,
|
|
start: arg.start,
|
|
end: arg.end,
|
|
allDay: arg.allDay
|
|
})
|
|
}
|
|
calendar.unselect()
|
|
|
|
},
|
|
eventClick: function(arg) {
|
|
if (confirm('Are you sure you want to delete this event?')) {
|
|
arg.event.remove()
|
|
}
|
|
},
|
|
});
|
|
calendar.render();
|
|
});
|
|
|
|
// When the 'upload' button is clicked...
|
|
document.getElementById("upload").addEventListener("click", function () {
|
|
//Cacultate data:
|
|
var calendarEvents = calendar.getEvents();
|
|
let schedule = []
|
|
//--------------------
|
|
for(i=0;i<calendarEvents.length;i++){
|
|
var calendarEntry = {}
|
|
calendarEntry['cn'] = calendarEvents[i].title;
|
|
calendarEntry['dow'] = calendarEvents[i].start.getDate()-3;
|
|
calendarEntry['sh'] = calendarEvents[i].start.getHours();
|
|
calendarEntry['sm'] = calendarEvents[i].start.getMinutes();
|
|
calendarEntry['eh'] = calendarEvents[i].end.getHours();
|
|
calendarEntry['em'] = calendarEvents[i].end.getMinutes();
|
|
schedule.push(calendarEntry)
|
|
}
|
|
// build the app's text using a templated String
|
|
var app = `
|
|
require("Font8x12").add(Graphics);
|
|
require("Font7x11Numeric7Seg", 2).add(Graphics);
|
|
var file = require("Storage").open("calendarItems.csv","w");
|
|
let nIntervId;
|
|
function redrawScreen() {
|
|
layout.render(layout.background);
|
|
layout.render(layout.buttons);
|
|
draw();
|
|
}
|
|
function updateDay(ffunction,day){
|
|
if(ffunction == 1){
|
|
switch (day) {
|
|
case 0:
|
|
return "Sunday";
|
|
case 1:
|
|
day = "Monday";
|
|
break;
|
|
case 2:
|
|
day = "Tuesday";
|
|
break;
|
|
case 3:
|
|
day = "Wednesday";
|
|
break;
|
|
case 4:
|
|
day = "Thursday";
|
|
break;
|
|
case 5:
|
|
day = "Friday";
|
|
break;
|
|
case 6:
|
|
day = "Saturday";
|
|
}
|
|
return day;
|
|
}else if(ffunction == 2){
|
|
switch (day) {
|
|
case 0:
|
|
return "Sun";
|
|
case 1:
|
|
day = "Mon";
|
|
break;
|
|
case 2:
|
|
day = "Tue";
|
|
break;
|
|
case 3:
|
|
day = "Wed";
|
|
break;
|
|
case 4:
|
|
day = "Thu";
|
|
break;
|
|
case 5:
|
|
day = "Fri";
|
|
break;
|
|
case 6:
|
|
day = "Sat";
|
|
}
|
|
return day;
|
|
}else if(ffunction == 3){
|
|
switch (day) {
|
|
case 0:
|
|
return "S";
|
|
case 1:
|
|
day = "M";
|
|
break;
|
|
case 2:
|
|
day = "T";
|
|
break;
|
|
case 3:
|
|
day = "W";
|
|
break;
|
|
case 4:
|
|
day = "R";
|
|
break;
|
|
case 5:
|
|
day = "F";
|
|
break;
|
|
case 6:
|
|
day = "S";
|
|
}
|
|
return day;
|
|
}
|
|
}
|
|
function getScheduleTable() {
|
|
let schedule = ${JSON.stringify(schedule)};
|
|
logDebug(JSON.stringify(schedule));
|
|
return schedule;
|
|
}
|
|
|
|
function findNextScheduleIndex() {
|
|
var schedule = getScheduleTable();
|
|
var currentDate = new Date();
|
|
var minuteOfWeek = (currentDate.getDay()*3600)+(currentDate.getHours()*60)+currentDate.getMinutes();
|
|
//var minuteOfWeek = (4*3600)+(16*60)+0;
|
|
var currentPosition;
|
|
for(currentPosition = 0;currentPosition < schedule.length; currentPosition++){
|
|
var scheduleItemStartMinuteOfWeek = schedule[currentPosition].dow*3600 + schedule[currentPosition].eh*60+schedule[currentPosition].em;
|
|
if(scheduleItemStartMinuteOfWeek > minuteOfWeek) {
|
|
return currentPosition;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
function getUpArrow() {return require("heatshrink").decompress(atob("hkOyANKmv9AIIjRCoYZRlvdAI8U3YVK3oBJC4Mc7YVRC4sc7gVCzoBNC4oZDGowXGR58lvoBFC9FcAIoXongBFC58dngBFC6EcAIoPHA"));}
|
|
function getDownArrow() {return require("heatshrink").decompress(atob("hkOyALImv9AIojPmvdAIoXPlvdAIoXQ3oBFC9GdAIoXnkt9AIoPPAI8U3cc7cc7gBBDIVcAJYXFGYwXOLpU8AI4XBO5sdjgBFR54ZFBpIA=="));}
|
|
function getMenuIcon() {return require("heatshrink").decompress(atob("iEQyBC/AEU+rwBEn02js17st3stvklrkljkc/cc3cUzYBBD5AdUD4oA/P/4A/P/4A/ADoA=="));}
|
|
function getDotIcon() {return require("heatshrink").decompress(atob("iEQyBC/AA0t3oBBA4ndAIIPGA4gAFkt9lt9AYIHEzoBBBIwRED41cks8AYIJGA44RGP8xtGP44RJBYh1CAIIHHBJJ/KroBBPoqBFB4YRDAA8dngHHBJKdq3oBDBI4RNP4l9AIYHHBJJBJks8AIIHTAH4ABA="));}
|
|
var currentPositionTable = 0;
|
|
var numberOfItemsShown = 8;
|
|
//Table Positions:
|
|
var rectStart = 45;
|
|
var rectEnd = 65;
|
|
var rectStartX = 10;
|
|
var rectEndX = 210;
|
|
//Scences:
|
|
LIST = 1;
|
|
INFORMATION = 2;
|
|
currentStage = LIST;
|
|
function splitter(str, l){
|
|
var strs = [];
|
|
while(str.length > l){
|
|
var pos = str.substring(0, l).lastIndexOf(' ');
|
|
pos = pos <= 0 ? l : pos;
|
|
strs.push(str.substring(0, pos));
|
|
var i = str.indexOf(' ', pos)+1;
|
|
if(i < pos || i > pos+l)
|
|
i = pos;
|
|
str = str.substring(i);
|
|
}
|
|
strs.push(str);
|
|
return strs;
|
|
}
|
|
function updateMinutesToCurrentTime(currentMinuteFunction) {
|
|
if (currentMinuteFunction<10){
|
|
currentMinuteUpdatedFunction = "0"+currentMinuteFunction;
|
|
}else{
|
|
currentMinuteUpdatedFunction = currentMinuteFunction;
|
|
}
|
|
return currentMinuteUpdatedFunction;
|
|
}
|
|
function renderBackground(l) {
|
|
g.clearRect(0,0,240,20);
|
|
g.drawImage(getBackgroundImage(),110,130,{scale:9,rotate:0});
|
|
}
|
|
function renderTable(l) {
|
|
var foundNumber = findNextScheduleIndex();
|
|
var yellowIndex = 3;
|
|
if (foundNumber < 3) { yellowIndex = foundNumber; }
|
|
for(var x = 0;x<=numberOfItemsShown;x++){
|
|
g.setColor(255,255,255);
|
|
g.drawRect(rectStartX,rectStart+(x*20),rectEndX,rectEnd+(20*x));
|
|
}
|
|
g.setColor(255,205,0);
|
|
g.drawRect(rectStartX,rectStart+(yellowIndex*20),rectEndX,rectEnd+(20*yellowIndex));
|
|
g.setColor(255,0,0);
|
|
g.drawRect(rectStartX,rectStart+(currentPositionTable*20),rectEndX,rectEnd+(20*currentPositionTable));
|
|
}
|
|
function renderTableText(l) {
|
|
var foundSchedule = getScheduleTable();
|
|
var foundNumber = findNextScheduleIndex();
|
|
var startNumber = foundNumber - 2;
|
|
if (startNumber < 0) { startNumber = 0; }
|
|
var endNumber = startNumber + 8 - (foundNumber - startNumber);
|
|
if (endNumber > foundSchedule.length-1) { endNumber = foundSchedule.length-1; }
|
|
var scheduleHourUpdated;
|
|
var scheduleMinuteUpdated;
|
|
for(var currentNumber = startNumber; currentNumber<=endNumber; currentNumber++){
|
|
scheduleMinuteUpdatedStart = updateMinutesToCurrentTime(foundSchedule[currentNumber].sm);
|
|
scheduleHourUpdatedStart = foundSchedule[currentNumber].sh;
|
|
scheduleMinuteUpdatedEnd = updateMinutesToCurrentTime(foundSchedule[currentNumber].em);
|
|
scheduleHourUpdatedEnd = foundSchedule[currentNumber].eh;
|
|
scheduleDecriptionUpdated = foundSchedule[currentNumber].cn.substring(0, 20);
|
|
if(foundSchedule[currentNumber].cn.length >= 15){
|
|
scheduleDecriptionUpdated = foundSchedule[currentNumber].cn.substring(0, 20)+"...";
|
|
}
|
|
schduleDay = updateDay(3,foundSchedule[currentNumber].dow);
|
|
g.setFont("8x12");
|
|
g.drawString(scheduleHourUpdatedStart+":"+scheduleMinuteUpdatedStart+"-"+scheduleHourUpdatedEnd+":"+scheduleMinuteUpdatedEnd+" "+schduleDay+" "+scheduleDecriptionUpdated,13,50+(currentNumber*20));
|
|
}
|
|
}
|
|
function buttonsF(l){
|
|
if(currentStage == LIST){
|
|
g.drawImage(getDotIcon(),223.5,115);
|
|
}else{
|
|
g.drawImage(getMenuIcon(),223.5,115);
|
|
}
|
|
g.drawImage(getUpArrow(),225,30);
|
|
g.drawImage(getDownArrow(),225,215);
|
|
}
|
|
function draw() {
|
|
var currentDate = new Date();
|
|
var currentDayOfWeek = currentDate.getDay();
|
|
var currentHour = currentDate.getHours();
|
|
var currentMinute = currentDate.getMinutes();
|
|
var currentMinuteUpdated = updateMinutesToCurrentTime(currentMinute);
|
|
if (layout) {
|
|
if(currentStage == LIST){
|
|
layout.time.label = currentHour+":"+currentMinuteUpdated;
|
|
layout.time.x = 147;
|
|
layout.time.y = 10;
|
|
layout.render(layout.table);
|
|
layout.render(layout.tableText);
|
|
logDebug("Rendered"+currentPositionTable);
|
|
}else{
|
|
layout.time.label = currentHour+":"+currentMinuteUpdated;
|
|
layout.time.x = 147;
|
|
layout.time.y = 10;
|
|
layout.render(layout.info);
|
|
logDebug("Rendered"+currentPositionTable);
|
|
}
|
|
g.clearRect(150,0,220,35);
|
|
layout.render(layout.time);
|
|
}
|
|
}
|
|
function RedRectDown() {
|
|
if(currentPositionTable > 0){
|
|
currentPositionTable -= 1;
|
|
if(currentStage == INFORMATION){
|
|
redrawScreen();
|
|
}else{
|
|
draw();
|
|
}
|
|
}
|
|
}
|
|
function RedRectUp() {
|
|
if(currentPositionTable < numberOfItemsShown){
|
|
currentPositionTable += 1;
|
|
if(currentStage == INFORMATION){
|
|
redrawScreen();
|
|
}else{
|
|
draw();
|
|
}
|
|
}
|
|
}
|
|
function renderMiniBackground(l){
|
|
for(var i = 233;i<=240;i++){
|
|
g.drawImage(getBackgroundImage(),i,123,{scale:10,rotate:0});
|
|
}
|
|
}
|
|
function renderLoading(l){
|
|
g.setFont("8x12");
|
|
g.drawString("Loading...",240/2-20,240/2-20);
|
|
}
|
|
function renderInformation(l){
|
|
var foundNumber = findNextScheduleIndex();
|
|
var foundSchedule = getScheduleTable();
|
|
var startNumber = foundNumber - 2;
|
|
if (startNumber < 0) { startNumber = 0; }
|
|
if ((startNumber+currentPositionTable) <= foundSchedule.length-1) {
|
|
scheduleMinuteUpdatedStart = updateMinutesToCurrentTime(foundSchedule[foundNumber].sm);
|
|
scheduleHourUpdatedStart = foundSchedule[foundNumber].sh;
|
|
scheduleMinuteUpdatedEnd = updateMinutesToCurrentTime(foundSchedule[foundNumber].em);
|
|
scheduleHourUpdatedEnd = foundSchedule[foundNumber].eh;
|
|
scheduleDay = updateDay(1,foundSchedule[(startNumber+currentPositionTable)].dow);
|
|
g.setColor(255,255,255);
|
|
g.setFont("8x12",2);
|
|
var splitClassNames = splitter(foundSchedule[(startNumber+currentPositionTable)].cn, 15);
|
|
var currentY = 5;
|
|
for (var j=0; j < splitClassNames.length; j++) {
|
|
g.drawString(splitClassNames[j],13,currentY+50);
|
|
currentY = currentY + 25;
|
|
}
|
|
g.setFont("8x12");
|
|
g.drawString(schduleDay,13,currentY+50);
|
|
g.drawString(scheduleHourUpdatedStart+":"+scheduleMinuteUpdatedStart+"-"+scheduleHourUpdatedEnd+":"+scheduleMinuteUpdatedEnd,13,currentY+15+50);
|
|
}
|
|
}
|
|
var Layout = require("Layout");
|
|
var layout = new Layout(
|
|
{type:"h", c: [
|
|
{type:"custom", render:renderTableText, id:"tableText"},
|
|
{type:"custom", render:buttonsF, id:"buttons"},
|
|
{type:"custom", render:renderBackground, id:"background"},
|
|
{type:"custom", render:renderTable, id:"table"},
|
|
{type:"custom", render:renderMiniBackground, id:"miniBackground"},
|
|
{type:"custom", render:renderLoading, id:"loading"},
|
|
{type:"custom", render:renderInformation, id:"info"},
|
|
{type:"txt", font:"7x11Numeric7Seg:2", label:"00:00", id:"time"},
|
|
]},
|
|
{type:"v", c:[
|
|
]},
|
|
{btns:[
|
|
{label:"", cb: RedRectUp()},
|
|
{label:"", cb: l=>print("Two")},
|
|
{label:"", cb: RedRectDown()}
|
|
]});
|
|
function getBackgroundImage() {return require("heatshrink").decompress(atob("j0ZyEKIf4A4gIB6gQB6gYB6ggB6goB6gwB6g4B6hAABAYIBHBZIVLAK8IhIBXgAThhQB6hYB6hgB6hoB6hwB6h4B6iAB6iIB6iQBHiAJOB54XSiYB6igB6ioB6iwB6i4B5A="));}
|
|
function logDebug(message) {console.log(message);}
|
|
function changeScene(){
|
|
layout.render(layout.buttons);
|
|
if(currentStage == INFORMATION){
|
|
currentStage = LIST;
|
|
nIntervId = setInterval(redrawScreen, 100000);
|
|
}else if(currentStage == LIST){
|
|
currentStage = INFORMATION;
|
|
clearInterval();
|
|
}
|
|
layout.render(layout.background);
|
|
layout.render(layout.buttons);
|
|
draw();
|
|
}
|
|
// timeout used to update every minute
|
|
var drawTimeout;
|
|
setInterval(draw, 15000);
|
|
setWatch(RedRectUp, BTN3, { repeat:true, edge:'rising', debounce : 50 });
|
|
setWatch(RedRectDown, BTN1, { repeat:true, edge:'rising', debounce : 50 });
|
|
setWatch(changeScene, BTN2, { repeat:true, edge:'rising', debounce : 50 });
|
|
layout.update();
|
|
layout.render(layout.loading);
|
|
layout.render(layout.background);
|
|
layout.render(layout.buttons);
|
|
draw();
|
|
file.write(JSON.stringify(schedule));
|
|
`;
|
|
// send finished app (in addition to contents of app.json)
|
|
sendCustomizedApp({
|
|
storage: [
|
|
{ name: "schoolCalendar.app.js", url: "app.js", content: app },
|
|
]
|
|
});
|
|
});
|
|
</script>
|
|
<div id='calendar'></div>
|
|
</body>
|
|
</html>
|