@@ -81,7 +81,7 @@ var onMessagesModified = function(type,msg) {
8181 require ( "messages" ) . apply ( msg , MESSAGES ) ;
8282 // TODO: if new, show this new one
8383 if ( msg && msg . id !== "music" && msg . id !== "nav" && msg . new &&
84- ! ( ( require ( 'Storage' ) . readJSON ( 'setting.json' , 1 ) || { } ) . quiet ) ) {
84+ ! ( ( require ( 'Storage' ) . readJSON ( 'setting.json' , 1 ) || { } ) . quiet ) ) {
8585 require ( "messages" ) . buzz ( msg . src ) ;
8686 }
8787 if ( msg && msg . id == "music" ) {
@@ -90,7 +90,8 @@ var onMessagesModified = function(type,msg) {
9090 }
9191 if ( msg && msg . id == "nav" && msg . t == "modify" && active != "map" )
9292 return ; // don't show an updated nav message if we're just in the menu
93- showMessage ( msg && msg . id , false ) ;
93+ //showMessage(msg&&msg.id, false);
94+ showMessagesScroller ( msg , false )
9495} ;
9596Bangle . on ( "message" , onMessagesModified ) ;
9697
@@ -105,35 +106,35 @@ function showMapMessage(msg) {
105106 var m , distance , street , target , img ;
106107 if ( "string" == typeof msg . distance ) // new gadgetbridge
107108 distance = msg . distance ;
108- else if ( "number" == typeof msg . distance ) // 0.74 gadgetbridge
109- distance = require ( "locale" ) . distance ( msg . distance ) ;
109+ else if ( "number" == typeof msg . distance ) // 0.74 gadgetbridge
110+ distance = require ( "locale" ) . distance ( msg . distance ) ;
110111 if ( msg . instr ) {
111112 var instr = msg . instr . replace ( / \s * \/ \s * / g, " \/\n" ) ; // convert slashes to newlines
112113 if ( instr . includes ( "towards" ) || instr . includes ( "toward" ) ) {
113114 m = instr . split ( / t o w a r d s | t o w a r d / ) ;
114115 target = m [ 0 ] . trim ( ) ;
115116 street = m [ 1 ] . trim ( ) ;
116117 } else
117- target = instr ;
118+ target = instr ;
118119 }
119120 var carIsRHD = ! ! settings . carIsRHD ;
120121 switch ( msg . action ) {
121- case "continue" : img = "EBgBAIABwAPgD/Af+D/8f/773/PPY8cDwAPAA8ADwAPAA8AAAAPAA8ADwAAAA8ADwAPA" ; break ;
122- case "left" : img = "GhcBAYAAAPAAAHwAAD4AAB8AAA+AAAf//8P///x///+PAAPx4AA8fAAHD4ABwfAAcDwAHAIABwAAAcAAAHAAABwAAAcAAAHAAABwAAAc" ; break ;
123- case "right" : img = "GhcBAABgAAA8AAAPgAAB8AAAPgAAB8D///j///9///+/AAPPAAHjgAD44AB8OAA+DgAPA4ABAOAAADgAAA4AAAOAAADgAAA4AAAOAAAA" ; break ;
124- case "left_slight" : img = "ERgB//B/+D/8H4AP4Af4A74Bz4Dj4HD4OD4cD4AD4ADwADwADgAHgAPAAOAAcAA4ABwADgAH" ; break ;
125- case "right_slight" : img = "ERgBB/+D/8H/4APwA/gD/APuA+cD44Phw+Dj4HPgAeAB4ADgAPAAeAA4ABwADgAHAAOAAcAA" ; break ;
126- case "left_sharp" : img = "GBaBAAAA+AAB/AAH/gAPjgAeBwA8BwB4B+DwB+HgB+PAB+eAB+8AB+4AB/wAB/gAB//gB//gB//gBwAABwAABwAABwAABw==" ; break ;
127- case "right_sharp" : img = "GBaBAB8AAD+AAH/gAHHwAOB4AOA8AOAeAOAPB+AHh+ADx+AB5+AA9+AAd+AAP+AAH+AH/+AH/+AH/+AAAOAAAOAAAOAAAA==" ; break ;
128- case "keep_left" : img = "ERmBAACAAOAB+AD+AP+B/+H3+PO+8c8w4wBwADgAHgAPAAfAAfAAfAAfAAeAAeAAcAA8AA4ABwADgA==" ; break ;
129- case "keep_right" : img = "ERmBAACAAOAA/AD+AP+A//D/fPueeceY4YBwADgAPAAeAB8AHwAfAB8ADwAPAAcAB4ADgAHAAOAAAA==" ; break ;
130- case "uturn_left" : img = "GRiBAAAH4AAP/AAP/wAPj8APAfAPAHgHgB4DgA8BwAOA4AHAcADsOMB/HPA7zvgd9/gOf/gHH/gDh/gBwfgA4DgAcBgAOAAAHAAADgAABw==" ; break ;
131- case "uturn_right" : img = "GRiBAAPwAAf+AAf/gAfj4AfAeAPAHgPADwHgA4DgAcBwAOA4AHAcBjhuB5x/A+57gP99wD/84A/8cAP8OAD8HAA4DgAMBwAAA4AAAcAAAA==" ; break ;
132- case "finish" : img = "HhsBAcAAAD/AAAH/wAAPB4AAeA4AAcAcAAYIcAA4cMAA48MAA4cMAAYAcAAcAcAAcA4AAOA4AAOBxjwHBzjwHjj/4Dnn/4B3P/4B+Pj4A8fj8Acfj8AI//8AA//+AA/j+AB/j+AB/j/A" ; break ;
133- case "roundabout_left" : img = carIsRHD ? "HBaCAAADwAAAAAAAD/AAAVUAAD/wABVVUAD/wABVVVQD/wAAVABUD/wAAVAAFT/////wABX/////8AAF//////AABT/////wABUP/AAD/AAVA/8AA/8AVAD/wAD//VQAP/AAP/1QAA/wAA/9AAADwAAD/AAAAAAAA/wAAAAAAAP8AAAAAAAD/AAAAAAAA/wAAAAAAAP8AAAAAAAD/AA=" : "HRYCAAPAAAAAAAAD/AAD//AAA/8AD///AAP/AA////AD/wAD/wP/A/8AA/wAP8P/////AAP//////8AA///////AAD/P////8AAP8P/AABUAD/AP/AAFUA/8AP/AAFX//AAP/AAFf/wAAP8AAB/8AAAPAAAD8AAAAAAAAPwAAAAAAAA/AAAAAAAAD8AAAAAAAAPwAAAAAAAA/AAAAAAAAD8AAA==" ; break ;
134- case "roundabout_right" : img = carIsRHD ? "HRaCAAAAAAAA8AAAP/8AAP8AAD///AA/8AA////AA/8AP/A/8AA/8A/wAP8AA/8P8AA/////8/wAD///////AAD//////8AAP////8P8ABUAAP/A/8AVQAD/wA//1UAA/8AA//VAAP/AAA/9AAA/wAAAPwAAA8AAAA/AAAAAAAAD8AAAAAAAAPwAAAAAAAA/AAAAAAAAD8AAAAAAAAPwAAAAAAA=" : "HBYCAAAAAAPAAABVQAAP8AAFVVQAD/wAFVVVAAP/ABUAFQAA/8BUAAVAAD/wVAAP/////FAAD/////9QAA//////VAAP/////FQAP8AAP/AVAP/AAP/AFX//AAP/AAV//AAP/AAAf/AAD/AAAD/AAAPAAAA/wAAAAAAAP8AAAAAAAD/AAAAAAAA/wAAAAAAAP8AAAAAAAD/AAAAAAA==" ; break ;
135- case "roundabout_straight" : img = carIsRHD ? "EBuCAAADwAAAD/AAAD/8AAD//wAD///AD///8D/P8/z/D/D//A/wPzAP8AwA//UAA//1QA//9VA/8AFUP8AAVD8AAFQ/AABUPwAAVD8AAFQ/wABUP/ABVA//9VAD//VAAP/1AAAP8AAAD/AAAA/wAA==" : "EBsCAAPAAAAP8AAAP/wAAP//AAP//8AP///wP8/z/P8P8P/8D/A/MA/wDABf/wABX//ABV//8BVAD/wVAAP8FQAA/BUAAPwVAAD8FQAA/BUAA/wVQA/8BV//8AFf/8AAX/8AAA/wAAAP8AAAD/AA" ; break ;
136- case "roundabout_uturn" : img = carIsRHD ? "ICCBAAAAAAAAAAAAAAAAAAAP4AAAH/AAAD/4AAB4fAAA8DwAAPAcAADgHgAA4B4AAPAcAADwPAAAeHwAADz4AAAc8AAABPAAAADwAAAY8YAAPPPAAD73gAAf/4AAD/8AABf8AAAb+AAAHfAAABzwAAAcYAAAAAAAAAAAAAAAAAAAAAAA" : "ICABAAAAAAAAAAAAAAAAAAfwAAAP+AAAH/wAAD4eAAA8DwAAOA8AAHgHAAB4BwAAOA8AADwPAAA+HgAAHzwAAA84AAAPIAAADwAAAY8YAAPPPAAB73wAAf/4AAD/8AAAP+gAAB/YAAAPuAAADzgAAAY4AAAAAAAAAAAAAAAAAAAAAAA=" ; break ;
122+ case "continue" : img = "EBgBAIABwAPgD/Af+D/8f/773/PPY8cDwAPAA8ADwAPAA8AAAAPAA8ADwAAAA8ADwAPA" ; break ;
123+ case "left" : img = "GhcBAYAAAPAAAHwAAD4AAB8AAA+AAAf//8P///x///+PAAPx4AA8fAAHD4ABwfAAcDwAHAIABwAAAcAAAHAAABwAAAcAAAHAAABwAAAc" ; break ;
124+ case "right" : img = "GhcBAABgAAA8AAAPgAAB8AAAPgAAB8D///j///9///+/AAPPAAHjgAD44AB8OAA+DgAPA4ABAOAAADgAAA4AAAOAAADgAAA4AAAOAAAA" ; break ;
125+ case "left_slight" : img = "ERgB//B/+D/8H4AP4Af4A74Bz4Dj4HD4OD4cD4AD4ADwADwADgAHgAPAAOAAcAA4ABwADgAH" ; break ;
126+ case "right_slight" : img = "ERgBB/+D/8H/4APwA/gD/APuA+cD44Phw+Dj4HPgAeAB4ADgAPAAeAA4ABwADgAHAAOAAcAA" ; break ;
127+ case "left_sharp" : img = "GBaBAAAA+AAB/AAH/gAPjgAeBwA8BwB4B+DwB+HgB+PAB+eAB+8AB+4AB/wAB/gAB//gB//gB//gBwAABwAABwAABwAABw==" ; break ;
128+ case "right_sharp" : img = "GBaBAB8AAD+AAH/gAHHwAOB4AOA8AOAeAOAPB+AHh+ADx+AB5+AA9+AAd+AAP+AAH+AH/+AH/+AH/+AAAOAAAOAAAOAAAA==" ; break ;
129+ case "keep_left" : img = "ERmBAACAAOAB+AD+AP+B/+H3+PO+8c8w4wBwADgAHgAPAAfAAfAAfAAfAAeAAeAAcAA8AA4ABwADgA==" ; break ;
130+ case "keep_right" : img = "ERmBAACAAOAA/AD+AP+A//D/fPueeceY4YBwADgAPAAeAB8AHwAfAB8ADwAPAAcAB4ADgAHAAOAAAA==" ; break ;
131+ case "uturn_left" : img = "GRiBAAAH4AAP/AAP/wAPj8APAfAPAHgHgB4DgA8BwAOA4AHAcADsOMB/HPA7zvgd9/gOf/gHH/gDh/gBwfgA4DgAcBgAOAAAHAAADgAABw==" ; break ;
132+ case "uturn_right" : img = "GRiBAAPwAAf+AAf/gAfj4AfAeAPAHgPADwHgA4DgAcBwAOA4AHAcBjhuB5x/A+57gP99wD/84A/8cAP8OAD8HAA4DgAMBwAAA4AAAcAAAA==" ; break ;
133+ case "finish" : img = "HhsBAcAAAD/AAAH/wAAPB4AAeA4AAcAcAAYIcAA4cMAA48MAA4cMAAYAcAAcAcAAcA4AAOA4AAOBxjwHBzjwHjj/4Dnn/4B3P/4B+Pj4A8fj8Acfj8AI//8AA//+AA/j+AB/j+AB/j/A" ; break ;
134+ case "roundabout_left" : img = carIsRHD ? "HBaCAAADwAAAAAAAD/AAAVUAAD/wABVVUAD/wABVVVQD/wAAVABUD/wAAVAAFT/////wABX/////8AAF//////AABT/////wABUP/AAD/AAVA/8AA/8AVAD/wAD//VQAP/AAP/1QAA/wAA/9AAADwAAD/AAAAAAAA/wAAAAAAAP8AAAAAAAD/AAAAAAAA/wAAAAAAAP8AAAAAAAD/AA=" : "HRYCAAPAAAAAAAAD/AAD//AAA/8AD///AAP/AA////AD/wAD/wP/A/8AA/wAP8P/////AAP//////8AA///////AAD/P////8AAP8P/AABUAD/AP/AAFUA/8AP/AAFX//AAP/AAFf/wAAP8AAB/8AAAPAAAD8AAAAAAAAPwAAAAAAAA/AAAAAAAAD8AAAAAAAAPwAAAAAAAA/AAAAAAAAD8AAA==" ; break ;
135+ case "roundabout_right" : img = carIsRHD ? "HRaCAAAAAAAA8AAAP/8AAP8AAD///AA/8AA////AA/8AP/A/8AA/8A/wAP8AA/8P8AA/////8/wAD///////AAD//////8AAP////8P8ABUAAP/A/8AVQAD/wA//1UAA/8AA//VAAP/AAA/9AAA/wAAAPwAAA8AAAA/AAAAAAAAD8AAAAAAAAPwAAAAAAAA/AAAAAAAAD8AAAAAAAAPwAAAAAAA=" : "HBYCAAAAAAPAAABVQAAP8AAFVVQAD/wAFVVVAAP/ABUAFQAA/8BUAAVAAD/wVAAP/////FAAD/////9QAA//////VAAP/////FQAP8AAP/AVAP/AAP/AFX//AAP/AAV//AAP/AAAf/AAD/AAAD/AAAPAAAA/wAAAAAAAP8AAAAAAAD/AAAAAAAA/wAAAAAAAP8AAAAAAAD/AAAAAAA==" ; break ;
136+ case "roundabout_straight" : img = carIsRHD ? "EBuCAAADwAAAD/AAAD/8AAD//wAD///AD///8D/P8/z/D/D//A/wPzAP8AwA//UAA//1QA//9VA/8AFUP8AAVD8AAFQ/AABUPwAAVD8AAFQ/wABUP/ABVA//9VAD//VAAP/1AAAP8AAAD/AAAA/wAA==" : "EBsCAAPAAAAP8AAAP/wAAP//AAP//8AP///wP8/z/P8P8P/8D/A/MA/wDABf/wABX//ABV//8BVAD/wVAAP8FQAA/BUAAPwVAAD8FQAA/BUAA/wVQA/8BV//8AFf/8AAX/8AAA/wAAAP8AAAD/AA" ; break ;
137+ case "roundabout_uturn" : img = carIsRHD ? "ICCBAAAAAAAAAAAAAAAAAAAP4AAAH/AAAD/4AAB4fAAA8DwAAPAcAADgHgAA4B4AAPAcAADwPAAAeHwAADz4AAAc8AAABPAAAADwAAAY8YAAPPPAAD73gAAf/4AAD/8AABf8AAAb+AAAHfAAABzwAAAcYAAAAAAAAAAAAAAAAAAAAAAA" : "ICABAAAAAAAAAAAAAAAAAAfwAAAP+AAAH/wAAD4eAAA8DwAAOA8AAHgHAAB4BwAAOA8AADwPAAA+HgAAHzwAAA84AAAPIAAADwAAAY8YAAPPPAAB73wAAf/4AAD/8AAAP+gAAB/YAAAPuAAADzgAAAY4AAAAAAAAAAAAAAAAAAAAAAA=" ; break ;
137138 }
138139
139140 layout = new Layout ( { type :"v" , c : [
@@ -196,7 +197,7 @@ function showMusicMessage(msg) {
196197 msg . new = false ;
197198 layout = undefined ;
198199 if ( wasNew ) checkMessages ( { clockIfNoMsg :1 , clockIfAllRead :1 , ignoreUnread :1 , openMusic :0 } ) ;
199- else returnToMain ( ) ;
200+ else returnToMain ( ) ;
200201 }
201202 function updateLabels ( ) {
202203 trackName = reduceStringAndPad ( msg . track , trackScrollOffset , 13 ) ;
@@ -246,44 +247,164 @@ function showMusicMessage(msg) {
246247 } , 400 ) ;
247248}
248249
249- function showMessageScroller ( msg ) {
250- cancelReloadTimeout ( ) ;
250+ function showMessagesScroller ( msg , persist , alreadyProcessed ) {
251+ if ( persist === undefined ) { persist = true ; }
252+ const MSG_IDX = msg ? MESSAGES . findIndex ( ( m ) => m . id == msg . id ) : 0 ;
253+ const INITIATED_FROM = (
254+ alreadyProcessed === undefined ? "other function" :
255+ ( MSG_IDX <= alreadyProcessed . idxSpan . start ? "scrolling up" :
256+ ( MSG_IDX >= alreadyProcessed . idxSpan . stop - 1 ? "scrolling down" :
257+ undefined ) )
258+ ) ;
259+ if ( ! alreadyProcessed ) { alreadyProcessed = { idxSpan :{ } } ; } // So `alreadyProcessed.idxSpan.start/stop` can be looked for on first run.
260+
261+ const WU = require ( "widget_utils" ) ;
262+ WU . hide ( ) ;
263+
264+ if ( replying ) { return ; }
265+ if ( persist ) { cancelReloadTimeout ( ) ; } else { resetReloadTimeout ( ) ; }
266+
267+ let idxSpan = (
268+ INITIATED_FROM === "other function" ?
269+ { start : Math . max ( MSG_IDX - 1 , 0 ) , stop : Math . min ( MSG_IDX + 2 , MESSAGES . length ) } :
270+ ( INITIATED_FROM === "scrolling up" ?
271+ { start : MSG_IDX , stop : alreadyProcessed . idxSpan . start } :
272+ ( INITIATED_FROM === "scrolling down" ?
273+ { start : alreadyProcessed . idxSpan . stop , stop : Math . min ( MSG_IDX + 1 , MESSAGES . length ) } :
274+ undefined ) )
275+ ) ;
276+
251277 active = "scroller" ;
252278 var bodyFont = fontBig ;
253279 g . setFont ( bodyFont ) ;
254- var lines = [ ] ;
255- if ( msg . title ) lines = g . wrapString ( msg . title , g . getWidth ( ) - 10 ) ;
256- var titleCnt = lines . length ;
257- if ( titleCnt ) lines . push ( "" ) ; // add blank line after title
258- lines = lines . concat ( g . wrapString ( msg . body , g . getWidth ( ) - 10 ) , [ "" , /*LANG*/ "< Back" ] ) ;
280+ var titleLines = [ ] ;
281+ var messagesWrapped = [ ] ;
282+ for ( let i = idxSpan . start ; i < idxSpan . stop ; i ++ ) {
283+ let msgLocal = MESSAGES [ i ] ;
284+ msgLocal . new = false ;
285+
286+ if ( msgLocal . id == "music" || msgLocal . source == "maps" || msgLocal . id == "call" ) {
287+ idxSpan . stop ++
288+ if ( idxSpan . stop >= MESSAGES . length ) { break ; }
289+ continue ;
290+ }
291+
292+ var lines = [ ] ;
293+ const TITLE_STRING = msgLocal . title || msgLocal . sender || msgLocal . subject || msgLocal . src || "No Title" ;
294+ //const TITLE_STRING = "".concat(msgLocal.title, msgLocal.title&&"\n",
295+ // msgLocal.sender, msgLocal.sender&&"\n",
296+ // msgLocal.subject, msgLocal.subject&&"\n", msgLocal.src) || "No Title";
297+ lines = g . wrapString ( TITLE_STRING , g . getWidth ( ) - 10 ) ;
298+ for ( let i = 0 ; i < lines . length ; i ++ ) {
299+ titleLines . push ( i + ( messagesWrapped [ 0 ] ?messagesWrapped [ 0 ] . length :0 ) +
300+ ( messagesWrapped [ 1 ] ?messagesWrapped [ 1 ] . length :0 ) ) ;
301+ }
302+ lines = lines . concat ( g . wrapString ( msgLocal . body , g . getWidth ( ) - 10 ) ,
303+ [ "-" . repeat ( 12 ) ] ) ;
304+ messagesWrapped . push ( lines ) ;
305+ }
306+
307+ let allLines = [ ] ;
308+ for ( let i = 0 ; i < messagesWrapped . length ; i ++ ) {
309+ allLines = allLines . concat ( messagesWrapped [ i ] ) ;
310+ }
311+
312+ var initScroll = messagesWrapped [ 0 ] . length ;
313+ if ( INITIATED_FROM === "other function" ) {
314+ if ( MSG_IDX == 0 ) { initScroll = 0 ; }
315+ } else if ( INITIATED_FROM === "scrolling up" ) {
316+ titleLines = titleLines . concat ( alreadyProcessed . titleLines .
317+ map ( ( x ) => x + allLines . length ) ) ;
318+ allLines = allLines . concat ( alreadyProcessed . lines ) ;
319+ } else if ( INITIATED_FROM === "scrolling down" ) {
320+ initScroll = alreadyProcessed . lines . length - ( g . getHeight ( ) / g . getFontHeight ( ) ) ;
321+ titleLines = alreadyProcessed . titleLines . concat ( titleLines .
322+ map ( ( x ) => x + alreadyProcessed . lines . length ) ) ;
323+ allLines = alreadyProcessed . lines . concat ( allLines ) ;
324+ }
325+
326+ if ( allLines . length == 0 && alreadyProcessed . lines . length == 0 ) {
327+ cancelReloadTimeout ( ) ;
328+ returnToClockIfEmpty ( ) ;
329+ }
330+
331+ alreadyProcessed = { // Update with the newly processed messages.
332+ lines : allLines ,
333+ titleLines : titleLines ,
334+ idxSpan : {
335+ start : Math . min ( idxSpan . start ,
336+ ( alreadyProcessed . idxSpan . start === undefined ) ?
337+ MESSAGES . length : alreadyProcessed . idxSpan . start ) ,
338+ stop : Math . max ( idxSpan . stop , alreadyProcessed . idxSpan . stop || 0 ) }
339+ } ;
340+
341+ let prevScrollIdx ; // Used for stopping repeated triggering of next message by the scroller.
342+
259343 E . showScroller ( {
344+ scroll : initScroll * g . getFontHeight ( ) ,
260345 h : g . getFontHeight ( ) , // height of each menu item in pixels
261- c : lines . length , // number of menu items
346+ c : allLines . length , // number of menu items
262347 // a function to draw a menu item
263- draw : function ( idx , r ) {
264- // FIXME: in 2v13 onwards, clearRect(r) will work fine. There's a bug in 2v12
265- g . setBgColor ( idx < titleCnt ? g . theme . bg2 : g . theme . bg ) .
266- setColor ( idx < titleCnt ? g . theme . fg2 : g . theme . fg ) .
267- clearRect ( r . x , r . y , r . x + r . w , r . y + r . h ) ;
268- g . setFont ( bodyFont ) . setFontAlign ( 0 , - 1 ) . drawString ( lines [ idx ] , r . x + r . w / 2 , r . y ) ;
269- } , select : function ( idx ) {
270- if ( idx >= lines . length - 2 )
271- showMessage ( msg . id , true ) ;
348+ draw : function ( scrollIdx , r ) {
349+ "ram" ;
350+ g . setBgColor ( titleLines . find ( e => e == scrollIdx ) !== undefined ? g . theme . bg2 : g . theme . bg ) .
351+ setColor ( titleLines . find ( e => e == scrollIdx ) !== undefined ? g . theme . fg2 : g . theme . fg ) .
352+ clearRect ( r ) ;
353+ g . setFont ( bodyFont ) . setFontAlign ( 0 , - 1 ) . drawString ( allLines [ scrollIdx ] , r . x + r . w / 2 , r . y ) ;
354+ // Load in next/previous message on demand by reinitializing showMessagesScroller while passing on the processed messages.
355+ if ( scrollIdx >= allLines . length - 1 && scrollIdx != prevScrollIdx &&
356+ alreadyProcessed . idxSpan . stop < MESSAGES . length ) {
357+ setTimeout ( ( ) => {
358+ E . showScroller ( ) ;
359+ showMessagesScroller ( MESSAGES [ alreadyProcessed . idxSpan . stop ] ,
360+ true , alreadyProcessed ) ;
361+ } , 40 ) ;
362+ }
363+ if ( scrollIdx == 0 && scrollIdx != prevScrollIdx && alreadyProcessed . idxSpan . start > 0 ) {
364+ setTimeout ( ( ) => {
365+ E . showScroller ( ) ;
366+ showMessagesScroller ( MESSAGES [ alreadyProcessed . idxSpan . start - 1 ] ,
367+ true , alreadyProcessed ) ;
368+ } , 40 ) ;
369+ }
370+ prevScrollIdx = scrollIdx ;
272371 } ,
273- back : ( ) => showMessage ( msg . id , true )
372+ select : function ( scrollIdx , touch ) {
373+ let msgSelect ;
374+ let firstTitleLinePerMsg = [ titleLines [ 0 ] ] ;
375+ for ( let i = 1 ; i < titleLines . length ; i ++ ) {
376+ if ( titleLines [ i ] - titleLines [ i - 1 ] === 1 ) { continue ; }
377+ firstTitleLinePerMsg . push ( titleLines [ i ] ) ;
378+ }
379+ for ( let i = titleLines . length - 1 ; i >= 0 ; i -- ) {
380+ if ( scrollIdx >= firstTitleLinePerMsg [ i ] ) {
381+ msgSelect = MESSAGES [ i + alreadyProcessed . idxSpan . start ] ;
382+ break ;
383+ }
384+ }
385+ if ( touch . type == 0 ) {
386+ WU . show ( ) ;
387+ showMessage ( msgSelect . id , true )
388+ }
389+ if ( touch . type == 2 ) {
390+ WU . show ( ) ;
391+ showMessageSettings ( msgSelect )
392+ }
393+ } ,
394+ //back : () => showMessage(messages[idx].id, true)
274395 } ) ;
275396}
276397
277398function showMessageSettings ( msg ) {
278399 active = "settings" ;
279400 var menu = { "" :{
280- "title" :/*LANG*/ "Message" ,
281- back :( ) => showMessage ( msg . id , true )
282- } ,
401+ "title" :/*LANG*/ "Message" ,
402+ back :( ) => showMessage ( msg . id , true )
403+ } ,
283404 } ;
284405
285406 if ( msg . id != "music" )
286- menu [ /*LANG*/ "View Message" ] = ( ) => showMessageScroller ( msg ) ;
407+ menu [ /*LANG*/ "View Message" ] = ( ) => showMessagesScroller ( msg ) ;
287408
288409 if ( msg . reply && reply ) {
289410 menu [ /*LANG*/ "Reply" ] = ( ) => {
@@ -392,7 +513,7 @@ function showMessage(msgid, persist) {
392513 var maxLines = Math . floor ( h / g . getFontHeight ( ) ) ;
393514 if ( lines . length > maxLines ) // if too long, wrap with a bit less spae so we have room for '...'
394515 body = g . setFont ( bodyFont ) . wrapString ( body , w - 10 ) . slice ( 0 , maxLines ) . join ( "\n" ) + "..." ;
395- else
516+ else
396517 body = lines . join ( "\n" ) ;
397518 }
398519 function goBack ( ) {
@@ -456,7 +577,7 @@ function showMessage(msgid, persist) {
456577 ] } ,
457578 { type :"txt" , font :bodyFont , label :body , fillx :1 , filly :1 , pad :2 , cb :( ) => {
458579 // allow tapping to show a larger version
459- showMessageScroller ( msg ) ;
580+ showMessagesScroller ( msg ) ;
460581 } } ,
461582 { type :"h" , fillx :1 , c : footer }
462583 ] } , { back :goBack } ) ;
@@ -502,7 +623,8 @@ function checkMessages(options) {
502623 // If we have a new message, show it
503624 if ( ! options . ignoreUnread && newMessages . length ) {
504625 delete newMessages [ 0 ] . show ; // stop us getting stuck here if we're called a second time
505- showMessage ( newMessages [ 0 ] . id , false ) ;
626+ //showMessage(newMessages[0].id, false);
627+ showMessagesScroller ( newMessages [ 0 ] , false ) ;
506628 // buzz after showMessage, so being busy during layout doesn't affect the buzz pattern
507629 if ( global . BUZZ_ON_NEW_MESSAGE ) {
508630 // this is set if we entered the messages app by loading `messagegui.new.js`
@@ -527,7 +649,7 @@ function checkMessages(options) {
527649 draw : function ( idx , r ) { "ram"
528650 var msg = MESSAGES [ idx ] ;
529651 if ( msg && msg . new ) g . setBgColor ( g . theme . bgH ) . setColor ( g . theme . fgH ) ;
530- else g . setBgColor ( g . theme . bg ) . setColor ( g . theme . fg ) ;
652+ else g . setBgColor ( g . theme . bg ) . setColor ( g . theme . fg ) ;
531653 g . clearRect ( r . x , r . y , r . x + r . w , r . y + r . h ) ;
532654 if ( ! msg ) return ;
533655 var x = r . x + 2 , title = msg . title , body = msg . body ;
@@ -538,9 +660,9 @@ function checkMessages(options) {
538660 }
539661 if ( img ) {
540662 var fg = g . getColor ( ) ,
541- col = require ( "messageicons" ) . getColor ( msg , { settings, default :fg } ) ;
663+ col = require ( "messageicons" ) . getColor ( msg , { settings, default :fg } ) ;
542664 g . setColor ( col ) . drawImage ( img , x + 24 , r . y + 24 , { rotate :0 } ) // force centering
543- . setColor ( fg ) ; // only color the icon
665+ . setColor ( fg ) ; // only color the icon
544666 x += 50 ;
545667 }
546668 if ( title ) g . setFontAlign ( - 1 , - 1 ) . setFont ( fontBig ) . drawString ( title , x , r . y + 2 ) ;
0 commit comments