2022-09-06 17:32:51 +00:00
Bangle . setUI ( "clock" ) ;
2022-03-05 10:37:35 +00:00
Bangle . loadWidgets ( ) ;
2022-03-05 08:26:40 +00:00
2022-03-05 10:37:35 +00:00
var s = Object . assign ( {
CAL _ROWS : 4 , //number of calendar rows.(weeks) Shouldn't exceed 5 when using widgets.
BUZZ _ON _BT : true , //2x slow buzz on disconnect, 2x fast buzz on connect. Will be extra widget eventually
MODE24 : true , //24h mode vs 12h mode
2022-03-23 13:37:44 +00:00
FIRSTDAY : 6 , //First day of the week: mo, tu, we, th, fr, sa, su
2022-03-05 10:37:35 +00:00
REDSUN : true , // Use red color for sunday?
REDSAT : true , // Use red color for saturday?
2022-03-23 13:37:44 +00:00
DRAGDOWN : "[AI:messg]" ,
DRAGRIGHT : "[AI:music]" ,
DRAGLEFT : "[ignore]" ,
DRAGUP : "[calend.]"
2022-03-05 10:37:35 +00:00
} , require ( 'Storage' ) . readJSON ( "clockcal.json" , true ) || { } ) ;
const h = g . getHeight ( ) ;
const w = g . getWidth ( ) ;
const CELL _W = w / 7 ;
2022-03-14 08:01:42 +00:00
const CELL2 _W = w / 8 ; //full calendar
2022-03-05 10:37:35 +00:00
const CELL _H = 15 ;
const CAL _Y = h - s . CAL _ROWS * CELL _H ;
const DEBUG = false ;
2022-03-14 08:01:42 +00:00
var state = "watch" ;
var monthOffset = 0 ;
2022-03-05 10:37:35 +00:00
2024-04-04 21:17:01 +00:00
// FIXME: These variables should maybe be defined inside relevant functions below. The linter complained they were not defined (i.e. they were added to global scope if I understand correctly).
let dayInterval ;
let secondInterval ;
let minuteInterval ;
let newmonth ;
let bottomrightY ;
let bottomrightX ;
let rMonth ;
let dimSeconds ;
2022-03-14 08:01:42 +00:00
/ *
* Calendar features
* /
function drawFullCalendar ( monthOffset ) {
2024-03-25 16:03:52 +00:00
const addMonths = function ( _d , _am ) {
let ay = 0 , m = _d . getMonth ( ) , y = _d . getFullYear ( ) ;
2022-03-23 13:37:44 +00:00
while ( ( m + _am ) > 11 ) { ay ++ ; _am -= 12 ; }
while ( ( m + _am ) < 0 ) { ay -- ; _am += 12 ; }
2024-03-25 16:03:52 +00:00
let n = new Date ( _d . getTime ( ) ) ;
2022-03-23 13:37:44 +00:00
n . setMonth ( m + _am ) ;
n . setFullYear ( y + ay ) ;
return n ;
2022-03-14 08:01:42 +00:00
} ;
monthOffset = ( typeof monthOffset == "undefined" ) ? 0 : monthOffset ;
state = "calendar" ;
var start = Date ( ) . getTime ( ) ;
const months = [ 'Jan.' , 'Feb' , 'Mar' , 'Apr' , 'May' , 'Jun' , 'Jul' , 'Aug' , 'Sep' , 'Oct' , 'Nov' , 'Dec.' ] ;
const monthclr = [ '#0f0' , '#f0f' , '#00f' , '#ff0' , '#0ff' , '#fff' ] ;
if ( typeof dayInterval !== "undefined" ) clearTimeout ( dayInterval ) ;
if ( typeof secondInterval !== "undefined" ) clearTimeout ( secondInterval ) ;
if ( typeof minuteInterval !== "undefined" ) clearTimeout ( minuteInterval ) ;
2024-03-25 16:03:52 +00:00
var d = addMonths ( Date ( ) , monthOffset ) ;
2024-04-04 21:17:01 +00:00
let tdy = Date ( ) . getDate ( ) + "." + Date ( ) . getMonth ( ) ;
2022-03-23 13:37:44 +00:00
newmonth = false ;
2024-04-04 21:17:01 +00:00
let c _y = 0 ;
2022-03-14 08:01:42 +00:00
g . reset ( ) ;
g . setBgColor ( 0 ) ;
g . clear ( ) ;
2022-03-23 13:37:44 +00:00
var prevmonth = addMonths ( d , - 1 ) ;
2022-03-14 08:01:42 +00:00
const today = prevmonth . getDate ( ) ;
var rD = new Date ( prevmonth . getTime ( ) ) ;
rD . setDate ( rD . getDate ( ) - ( today - 1 ) ) ;
2022-03-23 13:37:44 +00:00
const dow = ( s . FIRSTDAY + rD . getDay ( ) ) % 7 ;
2022-03-14 08:01:42 +00:00
rD . setDate ( rD . getDate ( ) - dow ) ;
var rDate = rD . getDate ( ) ;
bottomrightY = c _y - 3 ;
2024-04-04 21:17:01 +00:00
let clrsun = s . REDSUN ? '#f00' : '#fff' ;
let clrsat = s . REDSUN ? '#f00' : '#fff' ;
2022-03-23 13:37:44 +00:00
var fg = [ clrsun , '#fff' , '#fff' , '#fff' , '#fff' , '#fff' , clrsat ] ;
2022-03-14 08:01:42 +00:00
for ( var y = 1 ; y <= 11 ; y ++ ) {
bottomrightY += CELL _H ;
bottomrightX = - 2 ;
for ( var x = 1 ; x <= 7 ; x ++ ) {
bottomrightX += CELL2 _W ;
rMonth = rD . getMonth ( ) ;
rDate = rD . getDate ( ) ;
if ( tdy == rDate + "." + rMonth ) {
2022-03-23 13:37:44 +00:00
caldrawToday ( rDate ) ;
2022-03-14 08:01:42 +00:00
} else if ( rDate == 1 ) {
2022-03-23 13:37:44 +00:00
caldrawFirst ( rDate ) ;
2022-03-14 08:01:42 +00:00
} else {
2022-03-23 13:37:44 +00:00
caldrawNormal ( rDate , fg [ rD . getDay ( ) ] ) ;
2022-03-14 08:01:42 +00:00
}
if ( newmonth && x == 7 ) {
2022-03-23 13:37:44 +00:00
caldrawMonth ( rDate , monthclr [ rMonth % 6 ] , months [ rMonth ] , rD ) ;
2022-03-14 08:01:42 +00:00
}
rD . setDate ( rDate + 1 ) ;
}
}
delete addMonths ;
if ( DEBUG ) console . log ( "Calendar performance (ms):" + ( Date ( ) . getTime ( ) - start ) ) ;
}
2022-03-23 13:37:44 +00:00
function caldrawMonth ( rDate , c , m , rD ) {
2022-03-14 08:01:42 +00:00
g . setColor ( c ) ;
g . setFont ( "Vector" , 18 ) ;
g . setFontAlign ( - 1 , 1 , 1 ) ;
2024-04-04 21:17:01 +00:00
let drawyear = ( ( rMonth % 11 ) == 0 ) ? String ( rD . getFullYear ( ) ) . substr ( - 2 ) : "" ;
2022-03-14 08:01:42 +00:00
g . drawString ( m + drawyear , bottomrightX , bottomrightY - CELL _H , 1 ) ;
newmonth = false ;
}
function caldrawToday ( rDate ) {
2022-03-23 13:37:44 +00:00
g . setFont ( "Vector" , 16 ) ;
g . setFontAlign ( 1 , 1 ) ;
g . setColor ( '#0f0' ) ;
g . fillRect ( bottomrightX - CELL2 _W + 1 , bottomrightY - CELL _H - 1 , bottomrightX , bottomrightY - 2 ) ;
g . setColor ( '#000' ) ;
g . drawString ( rDate , bottomrightX , bottomrightY ) ;
2022-03-14 08:01:42 +00:00
}
function caldrawFirst ( rDate ) {
2022-03-23 13:37:44 +00:00
g . flip ( ) ;
g . setFont ( "Vector" , 16 ) ;
g . setFontAlign ( 1 , 1 ) ;
bottomrightY += 3 ;
newmonth = true ;
g . setColor ( '#0ff' ) ;
g . fillRect ( bottomrightX - CELL2 _W + 1 , bottomrightY - CELL _H - 1 , bottomrightX , bottomrightY - 2 ) ;
g . setColor ( '#000' ) ;
g . drawString ( rDate , bottomrightX , bottomrightY ) ;
2022-03-14 08:01:42 +00:00
}
2022-03-23 13:37:44 +00:00
function caldrawNormal ( rDate , c ) {
g . setFont ( "Vector" , 16 ) ;
g . setFontAlign ( 1 , 1 ) ;
g . setColor ( c ) ;
g . drawString ( rDate , bottomrightX , bottomrightY ) ; //100
2022-03-14 08:01:42 +00:00
}
2022-03-05 10:37:35 +00:00
function drawMinutes ( ) {
if ( DEBUG ) console . log ( "|-->minutes" ) ;
var d = new Date ( ) ;
var hours = s . MODE24 ? d . getHours ( ) . toString ( ) . padStart ( 2 , ' ' ) : ( ( d . getHours ( ) + 24 ) % 12 || 12 ) . toString ( ) . padStart ( 2 , ' ' ) ;
var minutes = d . getMinutes ( ) . toString ( ) . padStart ( 2 , '0' ) ;
2024-03-27 13:11:35 +00:00
var textColor = NRF . getSecurityStatus ( ) . connected ? '#fff' : '#f00' ;
2022-03-05 10:37:35 +00:00
var size = 50 ;
var clock _x = ( w - 20 ) / 2 ;
if ( dimSeconds ) {
size = 65 ;
clock _x = 4 + ( w / 2 ) ;
}
g . setBgColor ( 0 ) ;
g . setColor ( textColor ) ;
g . setFont ( "Vector" , size ) ;
g . setFontAlign ( 0 , 1 ) ;
g . drawString ( hours + ":" + minutes , clock _x , CAL _Y - 10 , 1 ) ;
var nextminute = ( 61 - d . getSeconds ( ) ) ;
if ( typeof minuteInterval !== "undefined" ) clearTimeout ( minuteInterval ) ;
minuteInterval = setTimeout ( drawMinutes , nextminute * 1000 ) ;
2022-03-05 08:26:40 +00:00
}
2022-03-05 10:37:35 +00:00
function drawSeconds ( ) {
if ( DEBUG ) console . log ( "|--->seconds" ) ;
var d = new Date ( ) ;
g . setColor ( ) ;
g . fillRect ( w - 31 , CAL _Y - 36 , w - 3 , CAL _Y - 19 ) ;
g . setBgColor ( 0 ) ;
g . setColor ( '#fff' ) ;
g . setFont ( "Vector" , 24 ) ;
g . setFontAlign ( 1 , 1 ) ;
g . drawString ( " " + d . getSeconds ( ) . toString ( ) . padStart ( 2 , '0' ) , w , CAL _Y - 13 ) ;
if ( typeof secondInterval !== "undefined" ) clearTimeout ( secondInterval ) ;
if ( ! dimSeconds ) secondInterval = setTimeout ( drawSeconds , 1000 ) ;
2022-03-05 08:26:40 +00:00
}
2022-03-14 08:01:42 +00:00
function drawWatch ( ) {
2024-03-23 04:39:11 +00:00
if ( DEBUG ) console . log ( "DRAWWATCH" ) ;
2022-03-14 08:01:42 +00:00
monthOffset = 0 ;
state = "watch" ;
2022-03-05 10:37:35 +00:00
var d = new Date ( ) ;
g . reset ( ) ;
g . setBgColor ( 0 ) ;
g . clear ( ) ;
drawMinutes ( ) ;
if ( ! dimSeconds ) drawSeconds ( ) ;
2022-03-23 13:37:44 +00:00
const dow = ( s . FIRSTDAY + d . getDay ( ) ) % 7 ; //MO=0, SU=6
2022-03-05 10:37:35 +00:00
const today = d . getDate ( ) ;
var rD = new Date ( d . getTime ( ) ) ;
rD . setDate ( rD . getDate ( ) - dow ) ;
var rDate = rD . getDate ( ) ;
g . setFontAlign ( 1 , 1 ) ;
for ( var y = 1 ; y <= s . CAL _ROWS ; y ++ ) {
for ( var x = 1 ; x <= 7 ; x ++ ) {
bottomrightX = x * CELL _W - 2 ;
bottomrightY = y * CELL _H + CAL _Y ;
g . setFont ( "Vector" , 16 ) ;
var fg = ( ( s . REDSUN && rD . getDay ( ) == 0 ) || ( s . REDSAT && rD . getDay ( ) == 6 ) ) ? '#f00' : '#fff' ;
if ( y == 1 && today == rDate ) {
g . setColor ( '#0f0' ) ;
g . fillRect ( bottomrightX - CELL _W + 1 , bottomrightY - CELL _H - 1 , bottomrightX , bottomrightY - 2 ) ;
g . setColor ( '#000' ) ;
g . drawString ( rDate , bottomrightX , bottomrightY ) ;
}
else {
g . setColor ( fg ) ;
g . drawString ( rDate , bottomrightX , bottomrightY ) ;
}
rD . setDate ( rDate + 1 ) ;
rDate = rD . getDate ( ) ;
}
2022-03-05 08:26:40 +00:00
}
2022-03-05 10:37:35 +00:00
Bangle . drawWidgets ( ) ;
2022-03-05 08:26:40 +00:00
2022-03-05 10:37:35 +00:00
var nextday = ( 3600 * 24 ) - ( d . getHours ( ) * 3600 + d . getMinutes ( ) * 60 + d . getSeconds ( ) + 1 ) ;
if ( DEBUG ) console . log ( "Next Day:" + ( nextday / 3600 ) ) ;
if ( typeof dayInterval !== "undefined" ) clearTimeout ( dayInterval ) ;
2022-03-14 08:01:42 +00:00
dayInterval = setTimeout ( drawWatch , nextday * 1000 ) ;
2024-03-23 04:39:11 +00:00
if ( DEBUG ) console . log ( "ended DRAWWATCH. next refresh in " + nextday + "s" ) ;
2022-03-05 08:26:40 +00:00
}
2022-03-05 10:37:35 +00:00
function BTevent ( ) {
drawMinutes ( ) ;
if ( s . BUZZ _ON _BT ) {
var interval = ( NRF . getSecurityStatus ( ) . connected ) ? 100 : 500 ;
Bangle . buzz ( interval ) ;
setTimeout ( function ( ) { Bangle . buzz ( interval ) ; } , interval * 3 ) ;
}
2022-03-05 08:26:40 +00:00
}
2022-03-23 13:37:44 +00:00
function action ( a ) {
g . reset ( ) ;
if ( typeof secondInterval !== "undefined" ) clearTimeout ( secondInterval ) ;
if ( DEBUG ) console . log ( "action:" + a ) ;
2024-03-23 04:39:11 +00:00
state = "unknown" ;
console . log ( "state -> unknown" ) ;
2024-04-04 21:17:01 +00:00
let l ;
2022-03-23 13:37:44 +00:00
switch ( a ) {
case "[ignore]" :
2024-03-23 04:39:11 +00:00
drawWatch ( ) ;
2022-03-23 13:37:44 +00:00
break ;
case "[calend.]" :
drawFullCalendar ( ) ;
break ;
case "[AI:music]" :
l = require ( "Storage" ) . list ( RegExp ( "music.*app.js" ) ) ;
if ( l . length > 0 ) {
load ( l [ 0 ] ) ;
} else E . showAlert ( "Music app not found" , "Not found" ) . then ( drawWatch ) ;
break ;
case "[AI:messg]" :
l = require ( "Storage" ) . list ( RegExp ( "message.*app.js" ) ) ;
if ( l . length > 0 ) {
load ( l [ 0 ] ) ;
} else E . showAlert ( "Message app not found" , "Not found" ) . then ( drawWatch ) ;
break ;
2024-03-23 05:02:30 +00:00
case "[AI:agenda]" :
l = require ( "Storage" ) . list ( RegExp ( "agenda.*app.js" ) ) ;
if ( l . length > 0 ) {
load ( l [ 0 ] ) ;
} else E . showAlert ( "Agenda app not found" , "Not found" ) . then ( drawWatch ) ;
break ;
2022-03-23 13:37:44 +00:00
default :
l = require ( "Storage" ) . list ( RegExp ( a + ".app.js" ) ) ;
if ( l . length > 0 ) {
load ( l [ 0 ] ) ;
} else E . showAlert ( a + ": App not found" , "Not found" ) . then ( drawWatch ) ;
break ;
}
}
2022-03-14 08:01:42 +00:00
function input ( dir ) {
2022-03-23 13:37:44 +00:00
Bangle . buzz ( 100 , 1 ) ;
if ( DEBUG ) console . log ( "swipe:" + dir ) ;
2022-03-14 08:01:42 +00:00
switch ( dir ) {
case "r" :
if ( state == "calendar" ) {
drawWatch ( ) ;
} else {
2022-03-23 13:37:44 +00:00
action ( s . DRAGRIGHT ) ;
2022-03-14 08:01:42 +00:00
}
break ;
case "l" :
if ( state == "calendar" ) {
drawWatch ( ) ;
2022-03-23 13:37:44 +00:00
} else {
action ( s . DRAGLEFT ) ;
2022-03-14 08:01:42 +00:00
}
break ;
case "d" :
if ( state == "calendar" ) {
monthOffset -- ;
drawFullCalendar ( monthOffset ) ;
} else {
2022-03-23 13:37:44 +00:00
action ( s . DRAGDOWN ) ;
2022-03-14 08:01:42 +00:00
}
break ;
case "u" :
2022-03-23 13:37:44 +00:00
if ( state == "calendar" ) {
2022-03-14 08:01:42 +00:00
monthOffset ++ ;
drawFullCalendar ( monthOffset ) ;
2022-03-23 13:37:44 +00:00
} else {
action ( s . DRAGUP ) ;
2022-03-14 08:01:42 +00:00
}
break ;
default :
if ( state == "calendar" ) {
drawWatch ( ) ;
}
break ;
}
}
let drag ;
Bangle . on ( "drag" , e => {
2022-03-23 13:37:44 +00:00
if ( ! drag ) {
drag = { x : e . x , y : e . y } ;
} else if ( ! e . b ) {
const dx = e . x - drag . x , dy = e . y - drag . y ;
var dir = "t" ;
if ( Math . abs ( dx ) > Math . abs ( dy ) + 20 ) {
dir = ( dx > 0 ) ? "r" : "l" ;
} else if ( Math . abs ( dy ) > Math . abs ( dx ) + 20 ) {
dir = ( dy > 0 ) ? "d" : "u" ;
2022-03-14 08:01:42 +00:00
}
2022-03-23 13:37:44 +00:00
drag = null ;
input ( dir ) ;
2022-03-14 08:01:42 +00:00
}
} ) ;
2022-03-05 10:37:35 +00:00
//register events
Bangle . on ( 'lock' , locked => {
if ( typeof secondInterval !== "undefined" ) clearTimeout ( secondInterval ) ;
dimSeconds = locked ; //dim seconds if lock=on
2022-03-14 08:01:42 +00:00
drawWatch ( ) ;
2022-03-05 10:37:35 +00:00
} ) ;
NRF . on ( 'connect' , BTevent ) ;
NRF . on ( 'disconnect' , BTevent ) ;
2022-03-05 08:26:40 +00:00
2022-03-05 10:37:35 +00:00
dimSeconds = Bangle . isLocked ( ) ;
2022-03-14 08:01:42 +00:00
drawWatch ( ) ;
2022-09-06 17:32:51 +00:00
2024-03-23 04:39:11 +00:00
setWatch ( function ( ) {
if ( state == "watch" ) {
Bangle . showLauncher ( )
} else if ( state == "calendar" ) {
drawWatch ( ) ;
}
} , BTN1 , { repeat : true , edge : "falling" } ) ;