1
- import html from ' html' ;
2
- import css from ' css' ;
1
+ import html from " html" ;
2
+ import css from " css" ;
3
3
4
- const HalfMeter = ( props ) => html `< path id ="halfMeter " d ="
4
+ const HalfMeter = ( props ) => html `< path
5
+ id ="halfMeter "
6
+ d ="
5
7
M50 0
6
8
A 50.4 50.4 0 0 0 7.2 76.5
7
9
l 8.7 -5.3 a 40.2 40.2 0 0 134.1 -61
8
10
z
9
- " ... ${ props } /> `;
11
+ "
12
+ ... ${ props }
13
+ /> `;
10
14
11
15
const Meter = ( ) => html `
12
16
< defs >
@@ -20,37 +24,44 @@ const Meter = () => html`
20
24
</ linearGradient >
21
25
</ defs >
22
26
< ${ HalfMeter } fill ="url('#cool')" />
23
- < ${ HalfMeter } transform ="translate(99, 0) scale(-1, 1)" fill="url('#warm')"/>
27
+ < ${ HalfMeter } transform ="translate(99, 0) scale(-1, 1)" fill="url('#warm')" />
24
28
` ;
25
29
26
30
const Marker = ( { temp, color } ) => {
27
31
if ( Number . isNaN ( parseFloat ( temp ) ) ) return null ;
28
32
return html `
29
- < g transform-origin ="50 50 " transform =${ `rotate(${ temp * 230 / 205 } )` } >
30
- < path d ="
33
+ < g transform-origin ="50 50 " transform =${ `rotate(${ ( temp * 230 ) / 205 } )` } >
34
+ < path
35
+ d ="
31
36
M 11, 69
32
37
l -7.3, 7.5
33
38
l -3.2, -6.8
34
- z " fill ="#111F "/>
35
- < path d ="
39
+ z "
40
+ fill ="#111F "
41
+ />
42
+ < path
43
+ d ="
36
44
M 9.6, 69.7
37
45
l -5.7, 5.5
38
46
l -2.2, -4.8
39
- z " fill =${ color } / >
47
+ z "
48
+ fill =${ color }
49
+ / >
40
50
</ g >
41
51
` ;
42
52
} ;
43
53
44
54
const Spread = ( ) => null ;
45
55
46
- const formatTemp = temp => Number . isNaN ( temp ) ? '--' : `${ ( temp * 9 / 5 + 32 ) . toFixed ( 0 ) } ºF` ;
47
- const tempColor = temp => {
48
- if ( Number . isNaN ( temp ) ) return '#292' ;
49
- console . log ( temp * 230 / 205 ) ;
50
- }
51
- const formatTime = ( time , retSecs ) => {
56
+ const formatTemp = ( temp ) =>
57
+ Number . isNaN ( temp ) ? "--" : `${ ( ( temp * 9 ) / 5 + 32 ) . toFixed ( 0 ) } ºF` ;
58
+ const tempColor = ( temp ) => {
59
+ if ( Number . isNaN ( temp ) ) return "#292" ;
60
+ console . log ( ( temp * 230 ) / 205 ) ;
61
+ } ;
62
+ const formatDuration = ( time , retSecs ) => {
52
63
const hours = Math . floor ( time / 3600 ) ;
53
- const minutes = Math [ retSecs ? ' floor' : ' round' ] ( ( time % 3600 ) / 60 ) ;
64
+ const minutes = Math [ retSecs ? " floor" : " round" ] ( ( time % 3600 ) / 60 ) ;
54
65
const block = [ ] ;
55
66
if ( hours ) {
56
67
block . unshift ( `${ hours . toFixed ( 0 ) } h` ) ;
@@ -63,7 +74,23 @@ const formatTime = (time, retSecs) => {
63
74
} else {
64
75
block . push ( `${ minutes . toFixed ( 0 ) } m` ) ;
65
76
}
66
- return block . join ( ' ' ) ;
77
+ return block . join ( " " ) ;
78
+ } ;
79
+
80
+ const formatEta = ( time , retSecs ) => {
81
+ const hours = Math . floor ( time / 3600 ) ;
82
+ const minutes = Math [ retSecs ? "floor" : "round" ] ( ( time % 3600 ) / 60 ) ;
83
+ const t = new Date ( ) ;
84
+ t . setHours ( t . getHours ( ) + hours ) ;
85
+ t . setMinutes ( t . getMinutes ( ) + minutes ) ;
86
+ if ( retSecs ) {
87
+ t . setSeconds ( t . getSeconds ( ) + ( time % 60 ) ) ;
88
+ }
89
+ let fmtTime = t . toLocaleTimeString ( ) ;
90
+ if ( ! retSecs ) {
91
+ fmtTime = fmtTime . replace ( / : \d { 2 } / , "" ) ;
92
+ }
93
+ return fmtTime . toLowerCase ( ) ;
67
94
} ;
68
95
69
96
const bubble = css `
@@ -85,14 +112,14 @@ const bubble = css`
85
112
` ;
86
113
87
114
const Bubble = ( { color, label, content } ) => html `
88
- < div
115
+ < div
89
116
className =${ bubble . circle }
90
117
style =${ {
91
118
backgroundColor : color ,
92
119
} }
93
120
>
94
121
< label > ${ label } </ label >
95
- < span > ${ content } </ span >
122
+ < span > ${ content } </ span >
96
123
</ div >
97
124
` ;
98
125
@@ -108,58 +135,76 @@ const styles = css`
108
135
font-family: Arial;
109
136
font-size: 10px;
110
137
text-anchor: middle;
111
- fill: #EEE ;
138
+ fill: #eee ;
112
139
text-shadow: 0 0 5px black;
113
140
}
114
141
` ;
115
142
export default ( {
116
143
width = 200 ,
117
- temperature : {
118
- internal,
119
- ambient
120
- } ,
144
+ temperature : { internal, ambient } ,
121
145
updated_at,
122
146
cook,
123
147
} ) => {
124
148
const {
125
149
name,
126
150
state,
127
- temperature : {
128
- peak,
129
- target,
130
- } = { } ,
131
- time : {
132
- elapsed,
133
- remaining,
134
- } = { } ,
151
+ temperature : { peak, target } = { } ,
152
+ time : { elapsed, remaining } = { } ,
135
153
} = cook || { } ;
136
- const lastUpdate = Math . round ( ( Date . now ( ) / 1000 ) - updated_at ) ;
154
+ const lastUpdate = Math . round ( Date . now ( ) / 1000 - updated_at ) ;
137
155
return html `
138
156
< div style =${ { width : `${ width } px` } } >
139
- < div className =${ styles . bubbles } style =${ { fontSize : `${ width * 12 / 200 } px` } } >
140
- < ${ Bubble } color ="#52E" label="Internal" content=${ formatTemp ( internal ) } />
141
- < ${ Bubble } color ="#3C3" label="Target" content=${ target ? formatTemp ( target ) : '--' } />
142
- < ${ Bubble } color ="#E52" label="Ambient" content=${ formatTemp ( ambient ) } />
157
+ < div
158
+ className =${ styles . bubbles }
159
+ style =${ { fontSize : `${ ( width * 12 ) / 200 } px` } }
160
+ >
161
+ < ${ Bubble }
162
+ color ="#52E"
163
+ label="Internal"
164
+ content=${ formatTemp ( internal ) }
165
+ />
166
+ < ${ Bubble }
167
+ color ="#3C3"
168
+ label="Target"
169
+ content=${ target ? formatTemp ( target ) : "--" }
170
+ />
171
+ < ${ Bubble }
172
+ color ="#E52"
173
+ label="Ambient"
174
+ content=${ formatTemp ( ambient ) }
175
+ />
143
176
</ div >
144
- < svg viewBox ="-5 -10 110 86 " width =${ width } height =${ width / 110 * 86 } >
177
+ < svg viewBox ="-5 -10 110 86 " width =${ width } height =${ ( width / 110 ) * 86 } >
145
178
< ${ Meter } />
146
179
< ${ Spread } low =${ peak } high=${ target } />
147
- < ${ Marker } color ="#52E" temp=${ internal || '--' } />
148
- < ${ Marker } color ="#3C3" temp=${ target || '--' } />
149
- < ${ Marker } color ="#E52" temp=${ ambient || '--' } />
180
+ < ${ Marker } color ="#52E" temp=${ internal || "--" } />
181
+ < ${ Marker } color ="#3C3" temp=${ target || "--" } />
182
+ < ${ Marker } color ="#E52" temp=${ ambient || "--" } />
150
183
< text className =${ styles . cook . toString ( ) } x ="50" y="50"> ${ name } </ text >
151
184
< text className =${ styles . cook . toString ( ) } x ="50" y="60">
152
- ${ remaining && remaining >= 0 && `ETA ${ formatTime ( remaining ) } ` }
153
- ${ remaining < 0 && ' Estimating ETA' }
154
- ${ remaining === undefined && '--' }
185
+ ${ remaining && remaining >= 0 && `... ${ formatDuration ( remaining ) } ` }
186
+ ${ remaining < 0 && " Estimating ETA" }
187
+ ${ remaining === undefined && "--" }
155
188
</ text >
156
- < text className =${ styles . cook . toString ( ) } x ="0" y="0" style="text-anchor: start;">
157
- ${ formatTime ( lastUpdate , true ) } ago
189
+ ${ remaining &&
190
+ remaining >= 0 &&
191
+ html `
192
+ < text className =${ styles . cook . toString ( ) } x ="50" y="70">
193
+ ETA ${ formatEta ( remaining ) }
194
+ </ text >
195
+ ` }
196
+ < text
197
+ className =${ styles . cook . toString ( ) }
198
+ x ="0"
199
+ y="0"
200
+ style="text-anchor: start;"
201
+ >
202
+ ${ formatDuration ( lastUpdate , true ) } ago
158
203
</ text >
159
204
< text className =${ styles . cook . toString ( ) } x ="50" y="30">
160
- for ${ formatTime ( elapsed ) }
205
+ for ${ formatDuration ( elapsed ) }
161
206
</ text >
162
207
</ svg >
163
208
</ div >
164
209
` ;
165
- } ;
210
+ } ;
0 commit comments