2021-10-22 10:47:23 +00:00
/ * M E S S A G E S i s a l i s t o f :
{ id : int ,
src ,
title ,
subject ,
body ,
sender ,
tel : string ,
new : true // not read yet
}
* /
/ * F o r e x a m p l e f o r m a p s :
2021-11-04 17:16:02 +00:00
// a message
{ "t" : "add" , "id" : 1575479849 , "src" : "Hangouts" , "title" : "A Name" , "body" : "message contents" }
// maps
{ "t" : "add" , "id" : 1 , "src" : "Maps" , "title" : "0 yd - High St" , "body" : "Campton - 11:48 ETA" , "img" : "GhqBAAAMAAAHgAAD8AAB/gAA/8AAf/gAP/8AH//gD/98B//Pg/4B8f8Afv+PP//n3/f5//j+f/wfn/4D5/8Aef+AD//AAf/gAD/wAAf4AAD8AAAeAAADAAA=" }
2021-11-23 16:28:34 +00:00
// call
2021-11-23 20:20:37 +00:00
{ "t" : "add" , "id" : "call" , "src" : "Phone" , "name" : "Bob" , "number" : "12421312" , positive : true , negative : true }
2021-10-22 10:47:23 +00:00
* /
var Layout = require ( "Layout" ) ;
2021-11-10 13:41:58 +00:00
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" ;
var colBg = g . theme . dark ? "#141" : "#4f4" ;
var colSBg1 = g . theme . dark ? "#121" : "#cFc" ;
var colSBg2 = g . theme . dark ? "#242" : "#9F9" ;
// hack for 2v10 firmware's lack of ':size' font handling
try {
g . setFont ( "6x8:2" ) ;
} catch ( e ) {
g . _setFont = g . setFont ;
g . setFont = function ( f , s ) {
if ( f . includes ( ":" ) ) {
f = f . split ( ":" ) ;
return g . _setFont ( f [ 0 ] , f [ 1 ] ) ;
}
return g . _setFont ( f , s ) ;
} ;
}
2021-10-22 10:47:23 +00:00
var MESSAGES = require ( "Storage" ) . readJSON ( "messages.json" , 1 ) || [ ] ;
if ( ! Array . isArray ( MESSAGES ) ) MESSAGES = [ ] ;
var onMessagesModified = function ( msg ) {
// TODO: if new, show this new one
if ( msg . new ) Bangle . buzz ( ) ;
showMessage ( msg . id ) ;
} ;
function saveMessages ( ) {
require ( "Storage" ) . writeJSON ( "messages.json" , MESSAGES )
}
2021-11-04 17:16:02 +00:00
function getBackImage ( ) {
return atob ( "FhYBAAAAEAAAwAAHAAA//wH//wf//g///BwB+DAB4EAHwAAPAAA8AADwAAPAAB4AAHgAB+AH/wA/+AD/wAH8AA==" ) ;
}
2021-11-23 20:20:37 +00:00
function getPosImage ( ) {
return atob ( "GRSBAAAAAYAAAcAAAeAAAfAAAfAAAfAAAfAAAfAAAfBgAfA4AfAeAfAPgfAD4fAA+fAAP/AAD/AAA/AAAPAAADAAAA==" ) ;
}
function getNegImage ( ) {
return atob ( "FhaBADAAMeAB78AP/4B/fwP4/h/B/P4D//AH/4AP/AAf4AB/gAP/AB/+AP/8B/P4P4fx/A/v4B//AD94AHjAAMA=" ) ;
}
2021-11-04 17:16:02 +00:00
function getMessageImage ( msg ) {
if ( msg . img ) return atob ( msg . img ) ;
var s = ( msg . src || "" ) . toLowerCase ( ) ;
2021-11-23 20:20:37 +00:00
if ( s == "Phone" ) return atob ( "FxeBABgAAPgAAfAAB/AAD+AAH+AAP8AAP4AAfgAA/AAA+AAA+AAA+AAB+AAB+AAB+OAB//AB//gB//gA//AA/8AAf4AAPAA=" ) ;
2021-11-04 17:16:02 +00:00
if ( s == "skype" ) return atob ( "GhoBB8AAB//AA//+Af//wH//+D///w/8D+P8Afz/DD8/j4/H4fP5/A/+f4B/n/gP5//B+fj8fj4/H8+DB/PwA/x/A/8P///B///gP//4B//8AD/+AAA+AA==" ) ;
if ( s == "hangouts" ) return atob ( "FBaBAAH4AH/gD/8B//g//8P//H5n58Y+fGPnxj5+d+fmfj//4//8H//B//gH/4A/8AA+AAHAABgAAAA=" ) ;
if ( s == "whatsapp" ) return atob ( "GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA==" ) ;
2021-11-22 07:18:47 +00:00
if ( s == "telegram" ) return atob ( "GBiBAAAAAAAAAAAAAAAAAwAAHwAA/wAD/wAf3gD/Pgf+fh/4/v/z/P/H/D8P/Acf/AM//AF/+AF/+AH/+ADz+ADh+ADAcAAAMAAAAA==" ) ;
2021-11-04 19:38:06 +00:00
if ( s == "twitter" ) return atob ( "GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA" ) ;
2021-11-04 17:16:02 +00:00
if ( msg . id == "music" ) return atob ( "FhaBAH//+/////////////h/+AH/4Af/gB/+H3/7/f/v9/+/3/7+f/vB/w8H+Dwf4PD/x/////////////3//+A=" ) ;
if ( msg . id == "back" ) return getBackImage ( ) ;
return atob ( "HBKBAD///8H///iP//8cf//j4//8f5//j/x/8//j/H//H4//4PB//EYj/44HH/Hw+P4//8fH//44///xH///g////A==" ) ;
}
2021-10-22 10:47:23 +00:00
function showMapMessage ( msg ) {
var m ;
var distance , street , target , eta ;
m = msg . title . match ( /(.*) - (.*)/ ) ;
if ( m ) {
distance = m [ 1 ] ;
street = m [ 2 ] ;
} else street = msg . title ;
m = msg . body . match ( /(.*) - (.*)/ ) ;
if ( m ) {
target = m [ 1 ] ;
eta = m [ 2 ] ;
} else target = msg . body ;
2021-11-04 17:16:02 +00:00
layout = new Layout ( { type : "v" , c : [
2021-11-10 13:41:58 +00:00
{ type : "txt" , font : fontMedium , label : target , bgCol : colBg , fillx : 1 , pad : 2 } ,
{ type : "h" , bgCol : colBg , fillx : 1 , c : [
2021-11-04 17:16:02 +00:00
{ type : "txt" , font : "6x8" , label : "Towards" } ,
2021-11-10 13:41:58 +00:00
{ type : "txt" , font : fontLarge , label : street }
2021-11-04 17:16:02 +00:00
] } ,
{ type : "h" , fillx : 1 , filly : 1 , c : [
msg . img ? { type : "img" , src : atob ( msg . img ) , scale : 2 } : { } ,
{ type : "v" , fillx : 1 , c : [
2021-11-10 13:41:58 +00:00
{ type : "txt" , font : fontLarge , label : distance || "" }
2021-10-22 10:47:23 +00:00
] } ,
2021-11-04 17:16:02 +00:00
] } ,
{ type : "txt" , font : "6x8:2" , label : eta }
] } ) ;
g . clearRect ( Bangle . appRect ) ;
2021-10-22 10:47:23 +00:00
layout . render ( ) ;
Bangle . setUI ( "updown" , function ( ) {
// any input to mark as not new and return to menu
msg . new = false ;
saveMessages ( ) ;
2021-11-04 17:16:02 +00:00
layout = undefined ;
2021-10-22 10:47:23 +00:00
checkMessages ( ) ;
} ) ;
}
2021-11-04 17:16:02 +00:00
function showMusicMessage ( msg ) {
function fmtTime ( s ) {
var m = Math . floor ( s / 60 ) ;
s = ( s % 60 ) . toString ( ) . padStart ( 2 , 0 ) ;
return m + ":" + s ;
}
function back ( ) {
msg . new = false ;
saveMessages ( ) ;
layout = undefined ;
checkMessages ( ) ;
}
layout = new Layout ( { type : "v" , c : [
2021-11-10 13:41:58 +00:00
{ type : "h" , fillx : 1 , bgCol : colBg , c : [
2021-11-04 17:16:02 +00:00
{ type : "btn" , src : getBackImage , cb : back } ,
{ type : "v" , fillx : 1 , c : [
2021-11-10 13:41:58 +00:00
{ type : "txt" , font : fontLarge , label : msg . artist , pad : 2 } ,
{ type : "txt" , font : fontMedium , label : msg . album , pad : 2 }
2021-11-04 17:16:02 +00:00
] }
] } ,
2021-11-10 13:41:58 +00:00
{ type : "txt" , font : fontLarge , label : msg . track , fillx : 1 , filly : 1 , pad : 2 } ,
2021-11-04 17:16:02 +00:00
Bangle . musicControl ? { type : "h" , fillx : 1 , c : [
{ type : "btn" , pad : 8 , label : "\0" + atob ( "FhgBwAADwAAPwAA/wAD/gAP/gA//gD//gP//g///j///P//////////P//4//+D//gP/4A/+AD/gAP8AA/AADwAAMAAA" ) , cb : ( ) => Bangle . musicControl ( "play" ) } , // play
{ type : "btn" , pad : 8 , label : "\0" + atob ( "EhaBAHgHvwP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP3gHg" ) , cb : ( ) => Bangle . musicControl ( "pause" ) } , // pause
{ type : "btn" , pad : 8 , label : "\0" + atob ( "EhKBAMAB+AB/gB/wB/8B/+B//B//x//5//5//x//B/+B/8B/wB/gB+AB8ABw" ) , cb : ( ) => Bangle . musicControl ( "next" ) } , // next
] } : { } ,
{ type : "txt" , font : "6x8:2" , label : msg . dur ? fmtTime ( msg . dur ) : "--:--" }
] } ) ;
g . clearRect ( Bangle . appRect ) ;
layout . render ( ) ;
}
2021-10-22 10:47:23 +00:00
function showMessage ( msgid ) {
var msg = MESSAGES . find ( m => m . id == msgid ) ;
if ( ! msg ) return checkMessages ( ) ; // go home if no message found
if ( msg . src == "Maps" ) return showMapMessage ( msg ) ;
2021-11-04 17:16:02 +00:00
if ( msg . id == "music" ) return showMusicMessage ( msg ) ;
// Normal text message display
2021-11-10 13:41:58 +00:00
var title = msg . title , titleFont = fontLarge ;
2021-11-04 17:16:02 +00:00
if ( title ) {
var w = g . getWidth ( ) - 40 ;
if ( g . setFont ( titleFont ) . stringWidth ( title ) > w )
2021-11-10 13:41:58 +00:00
titleFont = fontMedium ;
2021-11-04 17:16:02 +00:00
if ( g . setFont ( titleFont ) . stringWidth ( title ) > w )
title = g . wrapString ( title , w ) . join ( "\n" ) ;
}
2021-11-23 20:20:37 +00:00
var buttons = [
{ type : "btn" , src : getBackImage ( ) , cb : ( ) => checkMessages ( true ) } , // back
msg . new ? { type : "btn" , src : atob ( "HRiBAD///8D///wj///Fj//8bj//x3z//Hvx/8/fx/j+/x+Ad/B4AL8Rh+HxwH+PHwf+cf5/+x/n/PH/P8cf+cx5/84HwAB4fgAD5/AAD/8AAD/wAAD/AAAD8A==" ) , cb : ( ) => {
msg . new = false ; // read mail
saveMessages ( ) ;
checkMessages ( ) ;
} } : { }
] ;
if ( msg . positive ) {
buttons . push ( { type : "btn" , src : getPosImage ( ) , cb : ( ) => {
msg . new = false ; saveMessages ( ) ;
Bangle . messageResponse ( msg , true ) ;
checkMessages ( ) ;
} } ) ;
}
if ( msg . negative ) {
buttons . push ( { type : "btn" , src : getNegImage ( ) , cb : ( ) => {
msg . new = false ; saveMessages ( ) ;
Bangle . messageResponse ( msg , true ) ;
checkMessages ( ) ;
} } ) ;
}
2021-11-04 17:16:02 +00:00
layout = new Layout ( { type : "v" , c : [
2021-11-10 13:41:58 +00:00
{ type : "h" , fillx : 1 , bgCol : colBg , c : [
2021-11-04 17:16:02 +00:00
{ type : "img" , src : getMessageImage ( msg ) , pad : 2 } ,
{ type : "v" , fillx : 1 , c : [
2021-11-10 13:41:58 +00:00
{ type : "txt" , font : fontMedium , label : msg . src || "Message" , bgCol : colBg , fillx : 1 , pad : 2 } ,
title ? { type : "txt" , font : titleFont , label : title , bgCol : colBg , fillx : 1 , pad : 2 } : { } ,
2021-11-04 17:16:02 +00:00
] } ,
] } ,
2021-11-10 13:41:58 +00:00
{ type : "txt" , font : fontMedium , label : msg . body || "" , wrap : true , fillx : 1 , filly : 1 , pad : 2 } ,
2021-11-23 20:20:37 +00:00
{ type : "h" , fillx : 1 , c : buttons }
2021-11-04 17:16:02 +00:00
] } ) ;
g . clearRect ( Bangle . appRect ) ;
layout . render ( ) ;
2021-10-22 10:47:23 +00:00
}
function checkMessages ( forceShowMenu ) {
// If no messages, just show 'no messages' and return
2021-11-23 20:20:37 +00:00
if ( ! MESSAGES . length ) {
if ( forceShowMenu ) return E . showPrompt ( "No Messages" , {
2021-10-22 10:47:23 +00:00
title : "Messages" ,
img : require ( "heatshrink" ) . decompress ( atob ( "kkk4UBrkc/4AC/tEqtACQkBqtUDg0VqAIGgoZFDYQIIM1sD1QAD4AIBhnqA4WrmAIBhc6BAWs8AIBhXOBAWz0AIC2YIC5wID1gkB1c6BAYFBEQPqBAYXBEQOqBAnDAIQaEnkAngaEEAPDFgo+IKA5iIOhCGIAFb7RqAIGgtUBA0VqobFgNVA" ) ) ,
buttons : { "Ok" : 1 }
} ) . then ( ( ) => { load ( ) } ) ;
2021-11-23 20:20:37 +00:00
load ( ) ;
return ;
}
2021-10-22 10:47:23 +00:00
// we have >0 messages
2021-10-25 13:35:00 +00:00
// If we have a new message, show it
2021-10-22 10:47:23 +00:00
if ( ! forceShowMenu ) {
var newMessages = MESSAGES . filter ( m => m . new ) ;
if ( newMessages . length )
return showMessage ( newMessages [ 0 ] . id ) ;
}
// Otherwise show a menu
2021-10-25 13:35:00 +00:00
E . showScroller ( {
2021-10-22 10:47:23 +00:00
h : 48 ,
2021-11-23 20:20:37 +00:00
c : Math . min ( MESSAGES . length + 1 , 3 ) , // workaround for 2v10.219 firmware (min 3 not needed for 2v11)
2021-10-25 13:35:00 +00:00
draw : function ( idx , r ) { "ram"
var msg = MESSAGES [ idx - 1 ] ;
2021-11-10 13:41:58 +00:00
if ( msg && msg . new ) g . setBgColor ( colBg ) ;
else g . setBgColor ( ( idx & 1 ) ? colSBg1 : colSBg2 ) ;
2021-10-25 13:35:00 +00:00
g . clearRect ( r . x , r . y , r . x + r . w - 1 , r . y + r . h - 1 ) . setColor ( g . theme . fg ) ;
2021-11-04 17:16:02 +00:00
if ( idx == 0 ) msg = { id : "back" , title : "< Back" } ;
if ( ! msg ) return ;
var x = r . x + 2 , title = msg . title , body = msg . body ;
var img = getMessageImage ( msg ) ;
if ( msg . id == "music" ) {
title = msg . artist || "Music" ;
body = msg . track ;
}
if ( img ) {
g . drawImage ( img , x + 24 , r . y + 24 , { rotate : 0 } ) ; // force centering
x += 50 ;
}
2021-10-25 13:35:00 +00:00
var m = msg . title + "\n" + msg . body ;
2021-11-10 13:41:58 +00:00
if ( msg . src ) g . setFontAlign ( 1 , - 1 ) . setFont ( "6x8" ) . drawString ( msg . src , r . x + r . w - 2 , r . y + 2 ) ;
if ( title ) g . setFontAlign ( - 1 , - 1 ) . setFont ( fontBig ) . drawString ( title , x , r . y + 2 ) ;
2021-11-04 17:16:02 +00:00
if ( body ) {
2021-10-25 13:35:00 +00:00
g . setFontAlign ( - 1 , - 1 ) . setFont ( "6x8" ) ;
2021-11-04 17:16:02 +00:00
var l = g . wrapString ( body , r . w - 14 ) ;
2021-10-25 13:35:00 +00:00
if ( l . length > 3 ) {
l = l . slice ( 0 , 3 ) ;
l [ l . length - 1 ] += "..." ;
}
2021-11-04 17:16:02 +00:00
g . drawString ( l . join ( "\n" ) , x + 10 , r . y + 20 ) ;
2021-10-25 13:35:00 +00:00
}
} ,
select : idx => {
if ( idx == 0 ) load ( ) ;
else showMessage ( MESSAGES [ idx - 1 ] . id ) ;
}
2021-10-22 10:47:23 +00:00
} ) ;
}
2021-11-10 13:41:58 +00:00
g . clear ( ) ;
2021-10-22 10:47:23 +00:00
Bangle . loadWidgets ( ) ;
Bangle . drawWidgets ( ) ;
2021-11-23 20:20:37 +00:00
checkMessages ( true ) ; // force showing a menu