@@ -23,6 +23,22 @@ import { getTextWidth, isEdge, isIE, isRaspbian } from 'ks-util';
2323import { setSvgHref } from './util' ;
2424import { AppService } from './app.service' ;
2525
26+ const DEFAULT_BACKGROUND = 'midnightblue' ;
27+ const DEFAULT_FOREGROUND = 'white' ;
28+ const ERROR_BACKGROUND = '#CCC' ;
29+ const ERROR_FOREGROUND = 'black' ;
30+ const ADVISORY_BACKGROUND = 'cyan' ;
31+ const ADVISORY_FOREGROUND = 'black' ;
32+ const WATCH_BACKGROUND = 'orange' ;
33+ const WATCH_FOREGROUND = 'black' ;
34+ const WARNING_BACKGROUND = 'red' ;
35+ const WARNING_FOREGROUND = 'white' ;
36+
37+ const MARQUEE_SPEED = 100 ; // pixels per second
38+ const RASPBIAN_MARQUEE_FRAMERATE = 30 ; // frames per second
39+
40+ const FREQUENT_THRESHOLD = 300 ;
41+
2642interface CommonConditions {
2743 time : number ;
2844 summary : string ;
@@ -88,23 +104,23 @@ export class Forecast {
88104 private currentTemp : JQuery ;
89105 private feelsLike : JQuery ;
90106 private humidity : JQuery ;
91- private currentIcon : JQuery ;
92- private marquee : JQuery ;
107+ private readonly currentIcon : JQuery ;
108+ private readonly marquee : JQuery ;
93109
94110 private dayIcons : JQuery [ ] = [ ] ;
95111 private dayLowHighs : JQuery [ ] = [ ] ;
96112 private dayChancePrecips : JQuery [ ] = [ ] ;
97113 private dayPrecipAccums : JQuery [ ] = [ ] ;
98114
99- private weatherServer = '' ;
115+ private readonly weatherServer ;
100116
101117 private lastForecastData : ForecastData ;
102118 private timezone = KsTimeZone . OS_ZONE ;
103119
104120 private animationStyleSheet : CSSStyleSheet ;
105121 private keyframesIndex = 0 ;
106122 private lastMarqueeText = '' ;
107- private slowerFrameRate = false ;
123+ private readonly slowerFrameRate = isRaspbian ( ) ;
108124
109125 constructor ( private appService : AppService ) {
110126 this . currentTemp = $ ( '#current-temp' ) ;
@@ -123,13 +139,12 @@ export class Forecast {
123139
124140 if ( ! isIE ( ) && ! isEdge ( ) )
125141 this . weatherServer = new URL ( window . location . href ) . searchParams . get ( 'weather_server' ) || 'http://localhost:8080' ;
142+ else
143+ this . weatherServer = '' ;
126144
127145 window . addEventListener ( 'resize' , ( ) => this . updateMarqueeAnimation ( ) ) ;
128146 $ ( 'head' ) . append ( '<style id="marquee-animations" type="text/css"></style>' ) ;
129147 this . animationStyleSheet = ( $ ( '#marquee-animations' ) . get ( 0 ) as HTMLStyleElement ) . sheet as CSSStyleSheet ;
130-
131- if ( isRaspbian ( ) )
132- this . slowerFrameRate = true ;
133148 }
134149
135150 public update ( latitude : number , longitude : number , isMetric : boolean , amPm : boolean , userId ?: string ) : void {
@@ -165,12 +180,12 @@ export class Forecast {
165180 this . marquee . text ( error || '\u00A0' ) ;
166181
167182 if ( error ) {
168- this . marquee . css ( 'background-color' , '#CCC' ) ;
169- this . marquee . css ( 'color' , 'black' ) ;
183+ this . marquee . css ( 'background-color' , ERROR_BACKGROUND ) ;
184+ this . marquee . css ( 'color' , ERROR_FOREGROUND ) ;
170185 }
171186 else {
172- this . marquee . css ( 'background-color' , 'midnightblue' ) ;
173- this . marquee . css ( 'color' , 'white' ) ;
187+ this . marquee . css ( 'background-color' , DEFAULT_BACKGROUND ) ;
188+ this . marquee . css ( 'color' , DEFAULT_FOREGROUND ) ;
174189 }
175190
176191 this . updateMarqueeAnimation ( null ) ;
@@ -207,7 +222,7 @@ export class Forecast {
207222 if ( cacheControl ) {
208223 const match = / m a x - a g e = ( \d + ) / . exec ( cacheControl ) ;
209224
210- if ( match && Number ( match [ 1 ] ) <= 300 )
225+ if ( match && Number ( match [ 1 ] ) <= FREQUENT_THRESHOLD )
211226 data . frequent = true ;
212227 }
213228
@@ -371,23 +386,23 @@ export class Forecast {
371386
372387 switch ( maxSeverity ) {
373388 case 0 :
374- background = 'midnightblue' ;
375- color = 'white' ;
389+ background = DEFAULT_BACKGROUND ;
390+ color = DEFAULT_FOREGROUND ;
376391 break ;
377392
378393 case 1 :
379- background = 'cyan' ;
380- color = 'black' ;
394+ background = ADVISORY_BACKGROUND ;
395+ color = ADVISORY_FOREGROUND ;
381396 break ;
382397
383398 case 2 :
384- background = 'orange' ;
385- color = 'black' ;
399+ background = WATCH_BACKGROUND ;
400+ color = WATCH_FOREGROUND ;
386401 break ;
387402
388403 case 3 :
389- background = 'red' ;
390- color = 'white' ;
404+ background = WARNING_BACKGROUND ;
405+ color = WARNING_FOREGROUND ;
391406 break ;
392407 }
393408
@@ -397,8 +412,8 @@ export class Forecast {
397412 }
398413 else {
399414 this . marquee . text ( '\u00A0' ) ;
400- this . marquee . css ( 'background-color' , 'midnightblue' ) ;
401- this . marquee . css ( 'color' , 'white' ) ;
415+ this . marquee . css ( 'background-color' , DEFAULT_BACKGROUND ) ;
416+ this . marquee . css ( 'color' , DEFAULT_FOREGROUND ) ;
402417 }
403418
404419 this . updateMarqueeAnimation ( null ) ;
@@ -433,10 +448,10 @@ export class Forecast {
433448
434449 const keyframesName = 'marquee-' + this . keyframesIndex ++ ;
435450 const keyframesRule = `@keyframes ${ keyframesName } { 0% { text-indent: ${ offsetWidth } px } 100% { text-indent: -${ textWidth } px; } }` ;
436- const seconds = ( textWidth + offsetWidth ) / 100 ;
451+ const seconds = ( textWidth + offsetWidth ) / MARQUEE_SPEED ;
437452 // When the Raspberry Pi tries to scroll the marquee as fast as it can, the result is very jerky. It will be better
438453 // to have a slow but steady frame rate the Raspberry Pi can keep up with.
439- const linearOrSteps = ( this . slowerFrameRate ? `steps(${ Math . round ( seconds * 30 ) } )` : 'linear' ) ;
454+ const linearOrSteps = ( this . slowerFrameRate ? `steps(${ Math . round ( seconds * RASPBIAN_MARQUEE_FRAMERATE ) } )` : 'linear' ) ;
440455
441456 this . animationStyleSheet . insertRule ( keyframesRule , 0 ) ;
442457 this . marquee . css ( 'animation' , `${ keyframesName } ${ seconds } s infinite ${ linearOrSteps } ` ) ;
0 commit comments