2020-02-24 23:06:22 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
2020-05-23 12:43:59 +02:00
|
|
|
* limitations under the License.
|
2020-02-24 23:06:22 +01:00
|
|
|
*/
|
|
|
|
|
2020-05-23 23:50:21 +02:00
|
|
|
|
|
|
|
/* 'downloads' for debugging,
|
|
|
|
* 'wgt-private' for any release */
|
2020-08-13 21:04:08 +02:00
|
|
|
var STORAGE_SPACE = "downloads";
|
2020-05-24 13:07:57 +02:00
|
|
|
var SHORT_WAIT = 10000;
|
2020-08-13 21:04:08 +02:00
|
|
|
var LONG_WAIT = 30000; // 600000
|
2020-10-11 23:40:08 +02:00
|
|
|
var DESIGN = 2; // 0 - longitude, 1 - mission control, 2 - longitude
|
2020-05-24 13:07:57 +02:00
|
|
|
var wait_time = LONG_WAIT;
|
2020-05-23 22:19:31 +02:00
|
|
|
var events = null;
|
2020-05-23 23:50:21 +02:00
|
|
|
var deviceFingerprint = null;
|
2020-03-14 10:03:19 +01:00
|
|
|
var eventsTimeStamp = 0;
|
2020-08-13 21:04:08 +02:00
|
|
|
var flagDigital = true;
|
2020-03-14 10:03:19 +01:00
|
|
|
|
2020-02-24 23:06:22 +01:00
|
|
|
(function() {
|
|
|
|
var canvasLayout,
|
|
|
|
canvasContent,
|
|
|
|
ctxLayout,
|
|
|
|
ctxContent,
|
|
|
|
center,
|
|
|
|
watchRadius;
|
2020-05-23 22:19:31 +02:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
var flagConsole = true;
|
|
|
|
|
2020-05-24 13:07:57 +02:00
|
|
|
|
|
|
|
function deleteFile(name, callback) {
|
|
|
|
|
|
|
|
/* successful resolution of wgt-private */
|
|
|
|
function onsuccess(dir){
|
|
|
|
var dirfile = null;
|
|
|
|
try {
|
|
|
|
dirfile = dir.resolve(name);
|
|
|
|
} catch (exc) {
|
|
|
|
console.log(exc.message)
|
|
|
|
}
|
|
|
|
|
|
|
|
// if file not existed, call callback with null
|
|
|
|
if(dirfile == null) {
|
|
|
|
callback();
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// if file was found, delete it
|
|
|
|
dir.deleteFile(dirfile.fullPath, function() {
|
|
|
|
console.log("deleted");
|
|
|
|
callback();
|
|
|
|
},
|
|
|
|
function(e) {console.log(e)});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function onerror(e){
|
|
|
|
console.log("error"+e);
|
|
|
|
}
|
|
|
|
|
|
|
|
function onsuccessPermission(){
|
|
|
|
tizen.filesystem.resolve(STORAGE_SPACE, onsuccess, onerror, "rw");
|
|
|
|
}
|
|
|
|
|
|
|
|
function onErrorPermission(e){
|
|
|
|
console.log("error "+ JSON.stringify(e));
|
|
|
|
}
|
|
|
|
|
|
|
|
tizen.ppm.requestPermission("http://tizen.org/privilege/mediastorage", onsuccessPermission, onErrorPermission);
|
|
|
|
}
|
|
|
|
|
|
|
|
function clearDownloads() {
|
|
|
|
var onError = function(e) {
|
|
|
|
console.log('Error!' + e.message);
|
|
|
|
};
|
|
|
|
|
|
|
|
var onResolveSuccess = function(dir) {
|
|
|
|
var onListFilesSuccess = function(files) {
|
|
|
|
files.forEach(function(file) {
|
|
|
|
if (!file.isDirectory) {
|
|
|
|
dir.deleteFile(file.fullPath, onDeleteSuccess, onError);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
dir.listFiles(onListFilesSuccess, onError);
|
|
|
|
};
|
|
|
|
|
|
|
|
var onDeleteSuccess = function() {};
|
|
|
|
|
|
|
|
tizen.filesystem.resolve('/opt/usr/media/Downloads', onResolveSuccess, onError);
|
|
|
|
|
|
|
|
}
|
2020-02-24 23:06:22 +01:00
|
|
|
|
2020-05-23 22:19:31 +02:00
|
|
|
function getJsonFile(name, callback) {
|
2020-05-24 13:07:57 +02:00
|
|
|
console.log("searching for File");
|
2020-05-23 22:19:31 +02:00
|
|
|
/* successful resolution of wgt-private */
|
2020-05-23 12:43:59 +02:00
|
|
|
function onsuccess(dir){
|
2020-05-23 22:19:31 +02:00
|
|
|
var dirfile = null;
|
|
|
|
try {
|
|
|
|
dirfile = dir.resolve(name);
|
|
|
|
} catch (exc) {
|
|
|
|
console.log(exc.message)
|
|
|
|
}
|
|
|
|
|
2020-05-23 23:50:21 +02:00
|
|
|
// if file not existed, call callback with null
|
|
|
|
if(dirfile == null) {
|
|
|
|
callback(null)
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// if file was found, call callback with json
|
2020-05-23 12:43:59 +02:00
|
|
|
dirfile.openStream("r", function(fs) {
|
2020-05-23 22:19:31 +02:00
|
|
|
callback(JSON.parse(fs.read(dirfile.fileSize)));
|
|
|
|
fs.close();
|
|
|
|
});
|
2020-05-23 23:50:21 +02:00
|
|
|
}
|
2020-05-23 12:43:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function onerror(e){
|
|
|
|
console.log("error"+e);
|
|
|
|
}
|
|
|
|
|
|
|
|
function onsuccessPermission(){
|
2020-05-23 23:50:21 +02:00
|
|
|
tizen.filesystem.resolve(STORAGE_SPACE, onsuccess, onerror, "rw");
|
2020-02-24 23:06:22 +01:00
|
|
|
}
|
2020-05-23 12:43:59 +02:00
|
|
|
|
|
|
|
function onErrorPermission(e){
|
|
|
|
console.log("error "+ JSON.stringify(e));
|
|
|
|
}
|
|
|
|
|
|
|
|
tizen.ppm.requestPermission("http://tizen.org/privilege/mediastorage", onsuccessPermission, onErrorPermission);
|
2020-02-24 23:06:22 +01:00
|
|
|
}
|
2020-05-23 22:19:31 +02:00
|
|
|
|
2020-05-23 23:50:21 +02:00
|
|
|
function readJSON() {
|
2020-05-23 22:19:31 +02:00
|
|
|
/* - requests permission to view media storage
|
|
|
|
* - resolves the file 'calendarevents'
|
|
|
|
* - opens stream and reads entire file as json
|
|
|
|
*/
|
|
|
|
|
|
|
|
getJsonFile("calendarevents", function(eventlist) {events = eventlist;});
|
|
|
|
}
|
2020-05-23 23:50:21 +02:00
|
|
|
|
|
|
|
function getNewFingerprintFromServer() {
|
2020-08-13 21:04:08 +02:00
|
|
|
getFileFromServer("devicefingerprint.json", function() {
|
|
|
|
console.log("getting device fingerprint from server");
|
|
|
|
getJsonFile("devicefingerprint", function(df) {deviceFingerprint = df; console.log(deviceFingerprint);});
|
2020-05-23 23:50:21 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-02-24 23:06:22 +01:00
|
|
|
|
2020-05-23 23:50:21 +02:00
|
|
|
function getDeviceFingerprint() {
|
2020-05-23 22:19:31 +02:00
|
|
|
// check if device id set already as global, if it is return
|
2020-08-13 21:04:08 +02:00
|
|
|
if(deviceFingerprint !== null) {
|
2020-05-23 22:19:31 +02:00
|
|
|
return;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-05-23 22:19:31 +02:00
|
|
|
|
2020-05-23 23:50:21 +02:00
|
|
|
// otherwise, check if there is a devicefingerprint file in wgt-private
|
2020-05-23 22:19:31 +02:00
|
|
|
// if there is, open it up and get your device ID from it
|
2020-05-23 23:50:21 +02:00
|
|
|
getJsonFile("devicefingerprint", function(df) {
|
2020-08-13 21:04:08 +02:00
|
|
|
if(df !== null) {
|
2020-05-23 23:50:21 +02:00
|
|
|
deviceFingerprint = df;
|
|
|
|
} else {
|
|
|
|
// otherwise, ask the longitude server for a device fingerprint file
|
|
|
|
getNewFingerprintFromServer();
|
|
|
|
}
|
2020-08-13 21:04:08 +02:00
|
|
|
});
|
2020-05-23 22:19:31 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-05-23 23:50:21 +02:00
|
|
|
function getFileFromServer(route, callback) {
|
2020-05-24 13:07:57 +02:00
|
|
|
console.log("getting file");
|
2020-08-13 21:04:08 +02:00
|
|
|
var server = "https://longitudecalendar.com/";
|
2020-05-23 23:50:21 +02:00
|
|
|
var downloadRequest = new tizen.DownloadRequest(server + route, STORAGE_SPACE);
|
|
|
|
tizen.systeminfo.getPropertyValue('NETWORK', function(networkInfo) {
|
|
|
|
if (networkInfo.networkType === 'NONE') {
|
|
|
|
console.log('Network connection is not available.Download is not possible.');
|
|
|
|
downloadRequest = null;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
var listener = {
|
|
|
|
/* When the download progresses (interval is platform-dependent) */
|
|
|
|
onprogress: function(id, receivedSize, totalSize) {
|
|
|
|
console.log('progress for id: ' + id);
|
|
|
|
},
|
|
|
|
|
|
|
|
/* When the user pauses the download */
|
|
|
|
onpaused: function(id) {
|
|
|
|
console.log('Paused with id: ' + id);
|
|
|
|
},
|
|
|
|
|
|
|
|
/* When the user cancels the download */
|
|
|
|
oncanceled: function(id) {
|
|
|
|
console.log('Canceled with id: ' + id);
|
|
|
|
},
|
|
|
|
|
|
|
|
/* When the download is completed */
|
|
|
|
oncompleted: function(id, fullPath) {
|
|
|
|
console.log('Completed with id: ' + id + ', full path: ' + fullPath);
|
|
|
|
callback();
|
|
|
|
},
|
|
|
|
|
|
|
|
/* When the download fails */
|
|
|
|
onfailed: function(id, error) {
|
|
|
|
console.log('Failed with id: ' + id + ', error name: ' + error.name);
|
|
|
|
}
|
|
|
|
};
|
2020-05-24 13:07:57 +02:00
|
|
|
tizen.download.start(downloadRequest, listener);
|
2020-05-23 23:50:21 +02:00
|
|
|
}
|
2020-05-24 13:07:57 +02:00
|
|
|
|
|
|
|
function updateCalendar() {
|
2020-05-23 22:19:31 +02:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
if(deviceFingerprint === null) {
|
2020-05-24 13:07:57 +02:00
|
|
|
console.log("no fingerprint, loading from file or server");
|
2020-05-23 23:50:21 +02:00
|
|
|
getDeviceFingerprint();
|
2020-05-24 13:07:57 +02:00
|
|
|
wait_time = SHORT_WAIT;
|
2020-05-23 23:50:21 +02:00
|
|
|
return false;
|
|
|
|
}
|
2020-05-24 13:07:57 +02:00
|
|
|
|
|
|
|
function deleteCallback() {
|
|
|
|
console.log("done");
|
|
|
|
console.log("getting new calendar events");
|
2020-05-28 18:27:21 +02:00
|
|
|
getFileFromServer("device/" + deviceFingerprint.deviceName + "/calendarevents.json", readJSON);
|
|
|
|
}
|
2020-05-23 23:50:21 +02:00
|
|
|
|
2020-05-24 13:07:57 +02:00
|
|
|
console.log("deleting calendarevents");
|
|
|
|
deleteFile("calendarevents", deleteCallback);
|
|
|
|
|
2020-05-23 23:50:21 +02:00
|
|
|
return true;
|
2020-02-24 23:06:22 +01:00
|
|
|
}
|
|
|
|
|
2020-10-11 23:40:08 +02:00
|
|
|
function renderLine(context, p1, p2, thickness, color) {
|
|
|
|
context.save();
|
|
|
|
context.beginPath();
|
|
|
|
context.lineCap = "round";
|
|
|
|
context.lineWidth = thickness;
|
|
|
|
context.moveTo(p1.x, p1.y);
|
|
|
|
context.lineTo(p2.x, p2.y);
|
|
|
|
context.strokeStyle = color;
|
|
|
|
context.stroke();
|
|
|
|
context.restore();
|
|
|
|
}
|
|
|
|
|
2020-02-24 23:06:22 +01:00
|
|
|
/**
|
|
|
|
* Renders a circle with specific center, radius, and color
|
|
|
|
* @private
|
|
|
|
* @param {object} context - the context for the circle to be placed in
|
|
|
|
* @param {number} radius - the radius of the circle
|
|
|
|
* @param {string} color - the color of the circle
|
|
|
|
*/
|
|
|
|
function renderCircle(context, center, radius, color) {
|
|
|
|
context.save();
|
|
|
|
context.beginPath();
|
|
|
|
context.fillStyle = color;
|
|
|
|
context.arc(center.x, center.y, radius, 0, 2 * Math.PI);
|
|
|
|
context.fill();
|
|
|
|
context.closePath();
|
|
|
|
context.restore();
|
|
|
|
}
|
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
/**
|
|
|
|
* Renders a circle with specific center, radius, and color
|
|
|
|
* @private
|
|
|
|
* @param {object} context - the context for the circle to be placed in
|
|
|
|
* @param {number} radius - the radius of the circle
|
|
|
|
* @param {string} color - the color of the circle
|
|
|
|
*/
|
|
|
|
function renderRing(context, center, radius, width, color) {
|
|
|
|
context.save();
|
|
|
|
context.beginPath();
|
|
|
|
context.arc(center.x, center.y, radius, 0, 2 * Math.PI);
|
|
|
|
context.strokeStyle = color;
|
|
|
|
context.lineWidth = width;
|
|
|
|
context.stroke();
|
|
|
|
context.closePath();
|
|
|
|
context.restore();
|
|
|
|
}
|
|
|
|
|
2020-02-24 23:06:22 +01:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
function renderSimpleArc(context, center, radius, thickness, color, startAngle, endAngle) {
|
|
|
|
context.save();
|
|
|
|
context.beginPath();
|
|
|
|
|
|
|
|
context.arc(center.x, center.y, radius, startAngle * Math.PI / 180., endAngle * Math.PI / 180.);
|
|
|
|
context.fillStyle = color;
|
|
|
|
context.strokeStyle = color;
|
|
|
|
context.lineWidth = thickness;
|
|
|
|
context.stroke();
|
|
|
|
context.restore();
|
|
|
|
}
|
2020-02-24 23:06:22 +01:00
|
|
|
/**
|
|
|
|
* Renders a partial with specific center, radius, and color
|
|
|
|
* @private
|
|
|
|
* @param {object} context - the context for the circle to be placed in
|
|
|
|
* @param {number} radius - the radius of the circle
|
|
|
|
* @param {string} color - the color of the circle
|
|
|
|
*/
|
2020-08-13 21:04:08 +02:00
|
|
|
function renderArc(context, center, radius, thickness, color, startAngle, endAngle, hardStart, hardStop) {
|
2020-03-14 10:03:19 +01:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
if(hardStart == undefined) {
|
2020-03-14 10:03:19 +01:00
|
|
|
hardStart = false;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
|
|
|
if(hardStop == undefined) {
|
2020-03-14 10:03:19 +01:00
|
|
|
hardStop= false;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-05-16 17:24:16 +02:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
var seperation = 3;
|
2020-05-16 17:24:16 +02:00
|
|
|
// if arc size smaller than separation for circles or circle,
|
|
|
|
// draw a circle
|
|
|
|
|
|
|
|
var arcsize = 0;
|
|
|
|
if(endAngle < startAngle) {
|
|
|
|
arcsize = 360 - startAngle + endAngle;
|
|
|
|
} else {
|
|
|
|
arcsize = endAngle - startAngle;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(arcsize < 2*seperation) {
|
|
|
|
renderCircle(context, polToCart(radius, startAngle + arcsize /2 ), 9, color);
|
|
|
|
return;
|
|
|
|
}
|
2020-02-24 23:06:22 +01:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
if(!hardStart) {
|
2020-03-14 10:03:19 +01:00
|
|
|
startAngle += seperation;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-03-14 10:03:19 +01:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
if(startAngle >= 360) {
|
2020-02-24 23:06:22 +01:00
|
|
|
startAngle -= 360;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-02-24 23:06:22 +01:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
if(!hardStop) {
|
2020-03-14 10:03:19 +01:00
|
|
|
endAngle -= seperation;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-03-14 10:03:19 +01:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
if(endAngle<0) {
|
2020-02-24 23:06:22 +01:00
|
|
|
endAngle += 360;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-05-16 17:24:16 +02:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
// otherwise draw an arc and two circles
|
2020-05-16 17:24:16 +02:00
|
|
|
context.save();
|
|
|
|
context.beginPath();
|
|
|
|
|
2020-02-24 23:06:22 +01:00
|
|
|
context.arc(center.x, center.y, radius, startAngle * Math.PI / 180., endAngle * Math.PI / 180.);
|
|
|
|
context.fillStyle = color;
|
|
|
|
context.strokeStyle = color;
|
2020-08-13 21:04:08 +02:00
|
|
|
context.lineWidth = thickness;
|
2020-02-24 23:06:22 +01:00
|
|
|
context.stroke();
|
|
|
|
context.restore();
|
|
|
|
|
2020-03-14 10:03:19 +01:00
|
|
|
if(!hardStart)
|
|
|
|
renderCircle(context, polToCart(radius, startAngle), 9, color);
|
|
|
|
if(!hardStop)
|
|
|
|
renderCircle(context, polToCart(radius, endAngle), 9, color);
|
2020-02-24 23:06:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
function polToCart(radius, angle) {
|
|
|
|
pos = {
|
|
|
|
x: center.x + radius * Math.cos(angle * Math.PI / 180),
|
|
|
|
y: center.y + radius * Math.sin(angle * Math.PI / 180)
|
|
|
|
};
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
function hourToAngle(hour) {
|
2020-03-14 10:03:19 +01:00
|
|
|
if(hour >= 18)
|
|
|
|
hour -= 18;
|
|
|
|
else
|
|
|
|
hour += 6;
|
2020-08-13 21:04:08 +02:00
|
|
|
var angle = (hour) * 15;
|
2020-03-14 10:03:19 +01:00
|
|
|
|
|
|
|
return angle;
|
|
|
|
}
|
|
|
|
|
|
|
|
function minuteToAngle(minute) {
|
|
|
|
if(minute >= 15)
|
|
|
|
minute -= 15;
|
|
|
|
else
|
|
|
|
minute += 45;
|
|
|
|
angle = (minute / 60) * 360;
|
2020-02-24 23:06:22 +01:00
|
|
|
|
2020-03-14 10:03:19 +01:00
|
|
|
return angle;
|
2020-02-24 23:06:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Renders a needle with specific center, angle, start point, end point, width and color
|
|
|
|
* @private
|
|
|
|
* @param {object} context - the context for the needle to be placed in
|
|
|
|
* @param {number} angle - the angle of the needle (0 ~ 360)
|
|
|
|
* @param {number} startPoint - the start point of the needle (-1.0 ~ 1.0)
|
|
|
|
* @param {number} startPoint - the end point of the needle (-1.0 ~ 1.0)
|
|
|
|
* @param {number} width - the width of the needle
|
|
|
|
* @param {string} color - the color of the needle
|
|
|
|
*/
|
|
|
|
function renderNeedle(context, angle, startPoint, endPoint, width, color) {
|
|
|
|
var radius = context.canvas.width / 2,
|
|
|
|
centerX = context.canvas.width / 2,
|
|
|
|
centerY = context.canvas.height / 2,
|
|
|
|
dxi = radius * Math.cos(angle) * startPoint,
|
|
|
|
dyi = radius * Math.sin(angle) * startPoint,
|
|
|
|
dxf = radius * Math.cos(angle) * endPoint,
|
|
|
|
dyf = radius * Math.sin(angle) * endPoint;
|
|
|
|
|
|
|
|
context.save();
|
|
|
|
context.beginPath();
|
|
|
|
context.lineWidth = width;
|
|
|
|
context.strokeStyle = color;
|
|
|
|
context.moveTo(centerX + dxi, centerY + dyi);
|
|
|
|
context.lineTo(centerX + dxf, centerY + dyf);
|
|
|
|
context.stroke();
|
|
|
|
context.closePath();
|
|
|
|
context.restore();
|
|
|
|
}
|
2020-03-14 10:03:19 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Renders the 24h sun around the watch
|
|
|
|
*/
|
|
|
|
function renderSun(date, hour, minute, second) {
|
|
|
|
|
|
|
|
if(hour > 6 && hour < 18)
|
|
|
|
sunColor = "#FFD700";
|
|
|
|
else {
|
|
|
|
sunColor = "#C0C0C0"
|
|
|
|
}
|
|
|
|
|
|
|
|
sunDistance = document.body.clientWidth / 2 - 60;
|
|
|
|
renderCircle(ctxContent, polToCart(sunDistance, hourToAngle(hour + minute / 60)), 16, sunColor);
|
|
|
|
}
|
|
|
|
|
2020-10-03 18:40:20 +02:00
|
|
|
function renderSmallSun(date, hour, minute, second) {
|
|
|
|
|
2020-10-11 23:40:08 +02:00
|
|
|
sunColor = "#FFD700";
|
2020-10-03 18:40:20 +02:00
|
|
|
|
2020-10-03 23:01:23 +02:00
|
|
|
sunDistance = document.body.clientWidth / 2 - 40;
|
2020-10-11 23:40:08 +02:00
|
|
|
renderCircle(ctxContent, polToCart(sunDistance, hourToAngle(hour + minute / 60)), 10, sunColor);
|
2020-10-03 18:40:20 +02:00
|
|
|
}
|
|
|
|
|
2020-03-14 10:03:19 +01:00
|
|
|
function renderEarth(date, minute, second) {
|
|
|
|
|
2020-05-24 13:07:57 +02:00
|
|
|
var earthColor = "#0077BE";
|
|
|
|
var earthDistance = document.body.clientWidth / 2 - 120;
|
2020-03-14 10:03:19 +01:00
|
|
|
renderCircle(ctxContent, polToCart(earthDistance, minuteToAngle(minute + second / 60)), 10, earthColor);
|
|
|
|
}
|
|
|
|
|
2020-10-11 23:40:08 +02:00
|
|
|
function renderAnalog(hour, minute, second) {
|
|
|
|
// hour
|
|
|
|
var hourAngle = hourToAngle(hour + minute / 60)*2+180;
|
|
|
|
renderLine(ctxContent, polToCart(document.body.clientWidth / 2 - 120, hourAngle), polToCart(document.body.clientWidth / 2 - 60, hourAngle), 18, '#ffffff');
|
|
|
|
renderLine(ctxContent, polToCart(document.body.clientWidth / 2 - 120, hourAngle), polToCart(document.body.clientWidth / 2 - 60, hourAngle), 12, '#000000');
|
|
|
|
// minute
|
|
|
|
var minuteAngle = minuteToAngle(minute + second / 60);
|
|
|
|
renderLine(ctxContent, polToCart(document.body.clientWidth / 2 - 120, minuteAngle), polToCart(document.body.clientWidth / 2 - 40, minuteAngle), 18, '#ffffff');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-02-24 23:06:22 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Renders text at a specific center, radius, and color
|
|
|
|
* @private
|
|
|
|
* @param {object} context - the context for the text to be placed in
|
|
|
|
* @param {string} text - the text to be placed
|
|
|
|
* @param {number} x - the x-coordinate of the text
|
|
|
|
* @param {number} y - the y-coordinate of the text
|
|
|
|
* @param {number} textSize - the size of the text in pixel
|
|
|
|
* @param {string} color - the color of the text
|
|
|
|
*/
|
|
|
|
function renderText(context, text, x, y, textSize, color) {
|
|
|
|
context.save();
|
|
|
|
context.beginPath();
|
|
|
|
context.font = textSize + "px Courier";
|
|
|
|
context.textAlign = "center";
|
|
|
|
context.textBaseline = "middle";
|
|
|
|
context.fillStyle = color;
|
|
|
|
context.fillText(text, x, y);
|
|
|
|
context.closePath();
|
|
|
|
context.restore();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Draws the basic layout of the watch
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function drawWatchLayout() {
|
|
|
|
|
|
|
|
// Clear canvas
|
|
|
|
ctxLayout.clearRect(0, 0, ctxLayout.canvas.width, ctxLayout.canvas.height);
|
2020-08-13 21:04:08 +02:00
|
|
|
|
2020-02-24 23:06:22 +01:00
|
|
|
// Draw the background circle
|
|
|
|
/*
|
|
|
|
renderCircle(ctxLayout, center, watchRadius, "#000000");
|
|
|
|
grd = ctxLayout.createLinearGradient(0, 0, watchRadius * 2, 0);
|
|
|
|
grd.addColorStop(0, "#000000");
|
|
|
|
grd.addColorStop(0.5, "#454545");
|
|
|
|
grd.addColorStop(1, "#000000");
|
|
|
|
ctxLayout.fillStyle = grd;
|
|
|
|
renderCircle(ctxLayout, center, watchRadius * 0.945, grd);
|
|
|
|
renderCircle(ctxLayout, center, watchRadius * 0.7, "#000000");
|
|
|
|
*/
|
|
|
|
// Draw the dividers
|
|
|
|
// 60 unit divider
|
|
|
|
/*
|
|
|
|
for (i = 1; i <= 60; i++) {
|
|
|
|
angle = (i - 15) * (Math.PI * 2) / 60;
|
|
|
|
renderNeedle(ctxLayout, angle, 0.95, 1.0, 1, "#c4c4c4");
|
|
|
|
}
|
|
|
|
|
|
|
|
// 12 unit divider
|
|
|
|
for (j = 1; j <= 12; j++) {
|
|
|
|
angle = (j - 3) * (Math.PI * 2) / 12;
|
|
|
|
renderNeedle(ctxLayout, angle, 0.7, 0.945, 10, "#c4c4c4");
|
|
|
|
}
|
|
|
|
*/
|
2020-03-14 10:03:19 +01:00
|
|
|
|
|
|
|
// renderText(ctxLayout, "TIZEN WATCH", center.x, center.y - (watchRadius * 0.4), 25, "#999999");
|
2020-02-24 23:06:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Draws the content of the watch
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function drawWatchContent() {
|
2020-08-13 21:04:08 +02:00
|
|
|
var datetime = tizen.time.getCurrentDateTime();
|
2020-02-24 23:06:22 +01:00
|
|
|
|
|
|
|
// Clear canvas
|
|
|
|
ctxContent.clearRect(0, 0, ctxContent.canvas.width, ctxContent.canvas.height);
|
2020-03-14 10:03:19 +01:00
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
|
|
|
|
var hour = datetime.getHours(),
|
|
|
|
minute = datetime.getMinutes(),
|
|
|
|
second = datetime.getSeconds(),
|
|
|
|
date = datetime.getDate();
|
|
|
|
|
|
|
|
if(DESIGN === 0) {
|
|
|
|
renderSun(date, hour, minute, second);
|
|
|
|
renderEarth(ctxContent, minute, second);
|
|
|
|
} else if(DESIGN === 1) {
|
2020-10-03 18:40:20 +02:00
|
|
|
drawDigitalWatch();
|
|
|
|
} else if(DESIGN === 2) {
|
|
|
|
renderSmallSun(date, hour, minute, second);
|
2020-10-11 23:40:08 +02:00
|
|
|
drawDigitalWatch();
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-05-24 13:07:57 +02:00
|
|
|
/* if no return from server yet */
|
2020-08-13 21:04:08 +02:00
|
|
|
if(events === null) {
|
2020-03-14 10:03:19 +01:00
|
|
|
return;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-05-24 13:07:57 +02:00
|
|
|
|
2020-05-28 18:27:21 +02:00
|
|
|
/* if device not on server anymore */
|
2020-08-13 21:04:08 +02:00
|
|
|
if(events.kind === "not found") {
|
2020-05-28 18:27:21 +02:00
|
|
|
deviceFingerprint = null;
|
|
|
|
events = null;
|
|
|
|
deleteFile("devicefingerprint", function() {});
|
|
|
|
wait_time = SHORT_WAIT;
|
|
|
|
return;
|
|
|
|
}
|
2020-05-24 13:07:57 +02:00
|
|
|
/* if device not registered */
|
2020-08-13 21:04:08 +02:00
|
|
|
if(events.kind === "unregistered") {
|
2020-05-24 13:07:57 +02:00
|
|
|
wait_time = SHORT_WAIT;
|
|
|
|
if(deviceFingerprint === null) {
|
|
|
|
} else {
|
2020-05-28 18:27:21 +02:00
|
|
|
renderText(ctxContent, deviceFingerprint.deviceName, center.x, center.y, 20, "FF0000");
|
2020-05-24 13:07:57 +02:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
2020-08-13 21:04:08 +02:00
|
|
|
|
|
|
|
if(DESIGN === 0) {
|
|
|
|
var thickness = 18;
|
|
|
|
} else if(DESIGN === 1) {
|
|
|
|
var thickness = 50;
|
2020-10-03 18:40:20 +02:00
|
|
|
} else if(DESIGN === 2) {
|
|
|
|
var thickness = 18;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-05-24 13:07:57 +02:00
|
|
|
|
|
|
|
wait_time = LONG_WAIT;
|
|
|
|
|
2020-03-14 10:03:19 +01:00
|
|
|
|
|
|
|
for(var event in events.events){
|
|
|
|
var startedBeforeToday = false;
|
|
|
|
var endsAfterToday = false;
|
|
|
|
var e = events.events[event];
|
|
|
|
// check if not today
|
2020-08-13 21:04:08 +02:00
|
|
|
if(e.startDateTime.date.year !== tizen.time.getCurrentDateTime().getFullYear() ||
|
|
|
|
e.startDateTime.date.month !== tizen.time.getCurrentDateTime().getMonth() + 1 ||
|
|
|
|
e.startDateTime.date.day !== tizen.time.getCurrentDateTime().getDate()){
|
2020-03-14 10:03:19 +01:00
|
|
|
|
|
|
|
// if not today, check if it is an earlier event
|
2020-08-13 21:04:08 +02:00
|
|
|
if(e.startDateTime.date.year < tizen.time.getCurrentDateTime().getFullYear()) {
|
2020-03-14 10:03:19 +01:00
|
|
|
startedBeforeToday = true;
|
2020-08-13 21:04:08 +02:00
|
|
|
} else if(e.startDateTime.date.month < tizen.time.getCurrentDateTime().getMonth() + 1) {
|
2020-03-14 10:03:19 +01:00
|
|
|
startedBeforeToday = true;
|
2020-08-13 21:04:08 +02:00
|
|
|
} else if(e.startDateTime.date.day < tizen.time.getCurrentDateTime().getDate()) {
|
2020-03-14 10:03:19 +01:00
|
|
|
startedBeforeToday = true;
|
2020-08-13 21:04:08 +02:00
|
|
|
} else {
|
2020-03-14 10:03:19 +01:00
|
|
|
continue;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-03-14 10:03:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// check if not today
|
2020-08-13 21:04:08 +02:00
|
|
|
if(e.stopDateTime.date.year !== tizen.time.getCurrentDateTime().getFullYear() ||
|
|
|
|
e.stopDateTime.date.month !== tizen.time.getCurrentDateTime().getMonth() + 1 ||
|
|
|
|
e.stopDateTime.date.day !== tizen.time.getCurrentDateTime().getDate()){
|
2020-03-14 10:03:19 +01:00
|
|
|
|
|
|
|
// if not check if later date
|
2020-08-13 21:04:08 +02:00
|
|
|
if(e.stopDateTime.date.year > tizen.time.getCurrentDateTime().getFullYear()) {
|
2020-03-14 10:03:19 +01:00
|
|
|
endsAfterToday = true;
|
2020-08-13 21:04:08 +02:00
|
|
|
} else if(e.stopDateTime.date.month > tizen.time.getCurrentDateTime().getMonth() + 1) {
|
2020-03-14 10:03:19 +01:00
|
|
|
endsAfterToday = true;
|
2020-08-13 21:04:08 +02:00
|
|
|
} else if(e.stopDateTime.date.day > tizen.time.getCurrentDateTime().getDate()) {
|
2020-03-14 10:03:19 +01:00
|
|
|
endsAfterToday = true;
|
2020-08-13 21:04:08 +02:00
|
|
|
} else {
|
2020-03-14 10:03:19 +01:00
|
|
|
continue;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-03-14 10:03:19 +01:00
|
|
|
}
|
2020-08-13 21:04:08 +02:00
|
|
|
if(startedBeforeToday && endsAfterToday) {
|
2020-03-14 10:03:19 +01:00
|
|
|
continue;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-03-14 10:03:19 +01:00
|
|
|
|
|
|
|
var startTime = 0;
|
2020-08-13 21:04:08 +02:00
|
|
|
if(!startedBeforeToday) {
|
2020-03-14 10:03:19 +01:00
|
|
|
startTime = e.startDateTime.time.hour + e.startDateTime.time.minute / 60;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
|
|
|
var stopTime = 24;
|
|
|
|
if(!endsAfterToday) {
|
2020-03-14 10:03:19 +01:00
|
|
|
stopTime = e.stopDateTime.time.hour + e.stopDateTime.time.minute / 60;
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(DESIGN === 0) {
|
|
|
|
var edge = document.body.clientWidth / 2 - thickness / 2 - 2;
|
|
|
|
renderArc(ctxContent, center, edge, thickness, e.color, hourToAngle(startTime), hourToAngle(stopTime), startedBeforeToday, endsAfterToday);
|
|
|
|
} else if(DESIGN === 1) {
|
|
|
|
var edge = document.body.clientWidth / 2 - thickness / 2 - 2;
|
|
|
|
renderArc(ctxContent, center, edge, thickness, e.color, hourToAngle(startTime), hourToAngle(stopTime), true, true);
|
2020-10-03 18:40:20 +02:00
|
|
|
} else if(DESIGN === 2) {
|
|
|
|
var edge = document.body.clientWidth / 2 - thickness / 2 - 2;
|
|
|
|
renderArc(ctxContent, center, edge, thickness, e.color, hourToAngle(startTime), hourToAngle(stopTime), startedBeforeToday, endsAfterToday);
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-10-11 23:40:08 +02:00
|
|
|
|
|
|
|
if(eventNow(e, hour, minute)) {
|
|
|
|
drawEventName(e);
|
|
|
|
}
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if(DESIGN === 0) {
|
|
|
|
} else if(DESIGN === 1) {
|
|
|
|
var inner = document.body.clientWidth / 2 - thickness;
|
2020-08-15 10:14:46 +02:00
|
|
|
renderSimpleArc(ctxContent, center, 115, 8, "#FFFFFF", hourToAngle(20), hourToAngle(20+0.999))
|
2020-08-13 21:04:08 +02:00
|
|
|
for(var i = 0; i < 24; i++) {
|
|
|
|
renderSimpleArc(ctxContent, center, edge, thickness, "#000000", i*15-0.8, i*15+0.8);
|
|
|
|
}
|
2020-10-03 18:40:20 +02:00
|
|
|
} else if(DESIGN === 2) {
|
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
}
|
2020-10-11 23:40:08 +02:00
|
|
|
|
|
|
|
|
2020-08-13 21:04:08 +02:00
|
|
|
|
2020-03-14 10:03:19 +01:00
|
|
|
|
2020-10-11 23:40:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function eventNow(event, hour, minute) {
|
|
|
|
if( event.startDateTime.time.hour <= hour &&
|
|
|
|
event.startDateTime.time.minute <= minute &&
|
|
|
|
event.stopDateTime.time.hour >= hour &&
|
|
|
|
event.stopDateTime.time.minute >= minute) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function drawEventName(event) {
|
|
|
|
var strEvent = document.getElementById("str-event");
|
|
|
|
strEvent.innerHTML = event.name;
|
2020-03-14 10:03:19 +01:00
|
|
|
}
|
|
|
|
|
2020-10-03 18:40:20 +02:00
|
|
|
function drawDigitalWatch(datetime) {
|
2020-08-13 21:04:08 +02:00
|
|
|
var strHours = document.getElementById("str-hours"),
|
|
|
|
strConsole = document.getElementById("str-console"),
|
|
|
|
strMinutes = document.getElementById("str-minutes"),
|
|
|
|
datetime = tizen.time.getCurrentDateTime(),
|
|
|
|
hour = datetime.getHours(),
|
|
|
|
minute = datetime.getMinutes();
|
|
|
|
|
|
|
|
strHours.innerHTML = hour;
|
|
|
|
strMinutes.innerHTML = minute;
|
|
|
|
|
|
|
|
if (hour < 10) {
|
|
|
|
strHours.innerHTML = "0" + hour;
|
|
|
|
}
|
|
|
|
if (minute < 10) {
|
|
|
|
strMinutes.innerHTML = "0" + minute;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Each 0.5 second the visibility of flagConsole is changed.
|
|
|
|
if(flagDigital) {
|
|
|
|
if (flagConsole) {
|
|
|
|
strConsole.style.visibility = "visible";
|
|
|
|
flagConsole = false;
|
|
|
|
} else {
|
|
|
|
strConsole.style.visibility = "hidden";
|
|
|
|
flagConsole = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
strConsole.style.visibility = "visible";
|
|
|
|
flagConsole = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets to background image as BACKGROUND_URL,
|
|
|
|
* and starts timer for normal digital watch mode.
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function initDigitalWatch() {
|
|
|
|
flagDigital = true;
|
|
|
|
document.getElementById("digital-body").style.backgroundImage = BACKGROUND_URL;
|
|
|
|
interval = setInterval(updateTime, 500);
|
|
|
|
}
|
|
|
|
|
2020-05-24 13:07:57 +02:00
|
|
|
function loopCalendar(offset_ms) {
|
2020-03-14 10:03:19 +01:00
|
|
|
var d = new Date();
|
|
|
|
var currentTime = d.getTime();
|
|
|
|
if(eventsTimeStamp + offset_ms < currentTime){
|
2020-05-24 13:07:57 +02:00
|
|
|
updateCalendar();
|
2020-05-23 23:50:21 +02:00
|
|
|
eventsTimeStamp = currentTime;
|
|
|
|
}
|
2020-03-14 10:03:19 +01:00
|
|
|
|
|
|
|
|
2020-02-24 23:06:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set default variables
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function setDefaultVariables() {
|
|
|
|
canvasLayout = document.querySelector("#canvas-layout");
|
|
|
|
ctxLayout = canvasLayout.getContext("2d");
|
|
|
|
canvasContent = document.querySelector("#canvas-content");
|
|
|
|
ctxContent = canvasContent.getContext("2d");
|
|
|
|
|
|
|
|
// Set the canvases square
|
|
|
|
canvasLayout.width = document.body.clientWidth;
|
|
|
|
canvasLayout.height = canvasLayout.width;
|
|
|
|
canvasContent.width = document.body.clientWidth;
|
|
|
|
canvasContent.height = canvasContent.width;
|
|
|
|
|
|
|
|
center = {
|
|
|
|
x: document.body.clientWidth / 2,
|
|
|
|
y: document.body.clientHeight / 2
|
|
|
|
};
|
|
|
|
|
|
|
|
watchRadius = canvasLayout.width / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set default event listeners
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function setDefaultEvents() {
|
|
|
|
// add eventListener to update the screen immediately when the device wakes up
|
|
|
|
document.addEventListener("visibilitychange", function() {
|
|
|
|
if (!document.hidden) {
|
|
|
|
// Draw the content of the watch
|
|
|
|
drawWatchContent();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initiates the application
|
|
|
|
* @private
|
|
|
|
*/
|
|
|
|
function init() {
|
2020-05-24 13:07:57 +02:00
|
|
|
// clearDownloads();
|
2020-02-24 23:06:22 +01:00
|
|
|
setDefaultVariables();
|
|
|
|
setDefaultEvents();
|
|
|
|
|
|
|
|
// Draw the basic layout and the content of the watch at the beginning
|
|
|
|
drawWatchLayout();
|
|
|
|
drawWatchContent();
|
|
|
|
|
|
|
|
// Update the content of the watch every second
|
|
|
|
setInterval(function() {
|
|
|
|
drawWatchContent();
|
2020-05-24 13:07:57 +02:00
|
|
|
loopCalendar(wait_time);
|
2020-02-24 23:06:22 +01:00
|
|
|
}, 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
window.onload = init;
|
2020-05-16 17:24:16 +02:00
|
|
|
}());
|
|
|
|
|
|
|
|
document.addEventListener('ambientmodechanged', function(ev) {
|
|
|
|
var mode = ev.detail.ambientMode;
|
|
|
|
if (mode == true) {
|
|
|
|
/* Change the UI for ambient mode */
|
|
|
|
|
|
|
|
//updateAmbientWatchFaceDOM(); // function to rearange DOM for AOD mode
|
2020-08-13 21:04:08 +02:00
|
|
|
flagDigital = false;
|
2020-05-16 17:24:16 +02:00
|
|
|
updateTime();
|
|
|
|
} else {
|
|
|
|
/* Change the UI for normal mode */
|
|
|
|
|
|
|
|
// updateNormalWatchFaceDOM(); // function to rearange DOM for AOD mode
|
2020-08-13 21:04:08 +02:00
|
|
|
flagDigital = true;
|
2020-05-16 17:24:16 +02:00
|
|
|
updateTime();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
document.addEventListener('timetick', function(ev) {
|
|
|
|
/* Update the UI */
|
|
|
|
|
|
|
|
drawWatchContent();
|
2020-07-03 13:32:13 +02:00
|
|
|
});
|