1
- // Package browser provides the ability to send WebP images to a browser over
1
+ // Package browser provides the ability to send images to a browser over
2
2
// websockets.
3
3
package browser
4
4
@@ -19,17 +19,18 @@ import (
19
19
"tidbyt.dev/pixlet/server/loader"
20
20
)
21
21
22
- // Browser provides a structure for serving WebP images over websockets to
22
+ // Browser provides a structure for serving WebP or GIF images over websockets to
23
23
// a web browser.
24
24
type Browser struct {
25
25
addr string // The address to listen on.
26
26
title string // The title of the HTML document.
27
- updateChan chan loader.Update // A channel of base64 encoded WebP images.
27
+ updateChan chan loader.Update // A channel of base64 encoded images.
28
28
watch bool
29
29
fo * fanout.Fanout
30
30
r * mux.Router
31
31
tmpl * template.Template
32
32
loader * loader.Loader
33
+ serveGif bool // True if serving GIF, false if serving WebP
33
34
}
34
35
35
36
//go:embed preview-mask.png
@@ -43,18 +44,19 @@ var previewHTML string
43
44
44
45
// previewData is used to populate the HTML template.
45
46
type previewData struct {
46
- Title string `json:"title"`
47
- WebP string `json:"webp"`
48
- Watch bool `json:"-"`
49
- Err string `json:"error,omitempty"`
47
+ Title string `json:"title"`
48
+ Image string `json:"img"`
49
+ ImageType string `json:"img_type"`
50
+ Watch bool `json:"-"`
51
+ Err string `json:"error,omitempty"`
50
52
}
51
53
type handlerRequest struct {
52
54
ID string `json:"id"`
53
55
Param string `json:"param"`
54
56
}
55
57
56
58
// NewBrowser sets up a browser structure. Call Run() to kick off the main loops.
57
- func NewBrowser (addr string , title string , watch bool , updateChan chan loader.Update , l * loader.Loader ) (* Browser , error ) {
59
+ func NewBrowser (addr string , title string , watch bool , updateChan chan loader.Update , l * loader.Loader , serveGif bool ) (* Browser , error ) {
58
60
tmpl , err := template .New ("preview" ).Parse (previewHTML )
59
61
if err != nil {
60
62
return nil , err
@@ -68,6 +70,7 @@ func NewBrowser(addr string, title string, watch bool, updateChan chan loader.Up
68
70
title : title ,
69
71
loader : l ,
70
72
watch : watch ,
73
+ serveGif : serveGif ,
71
74
}
72
75
73
76
r := mux .NewRouter ()
@@ -92,6 +95,7 @@ func NewBrowser(addr string, title string, watch bool, updateChan chan loader.Up
92
95
// API endpoints to support the React frontend.
93
96
r .HandleFunc ("/api/v1/preview" , b .previewHandler )
94
97
r .HandleFunc ("/api/v1/preview.webp" , b .imageHandler )
98
+ r .HandleFunc ("/api/v1/preview.gif" , b .imageHandler )
95
99
r .HandleFunc ("/api/v1/push" , b .pushHandler )
96
100
r .HandleFunc ("/api/v1/schema" , b .schemaHandler ).Methods ("GET" )
97
101
r .HandleFunc ("/api/v1/handlers/{handler}" , b .schemaHandlerHandler ).Methods ("POST" )
@@ -103,7 +107,7 @@ func NewBrowser(addr string, title string, watch bool, updateChan chan loader.Up
103
107
104
108
// Run starts the server process and runs forever in a blocking fashion. The
105
109
// main routines include an update watcher to process incomming changes to the
106
- // webp and running the http handlers.
110
+ // image and running the http handlers.
107
111
func (b * Browser ) Run () error {
108
112
defer b .fo .Quit ()
109
113
@@ -170,17 +174,21 @@ func (b *Browser) imageHandler(w http.ResponseWriter, r *http.Request) {
170
174
config [k ] = val [0 ]
171
175
}
172
176
173
- webp , err := b .loader .LoadApplet (config )
177
+ img , err := b .loader .LoadApplet (config )
174
178
if err != nil {
175
179
http .Error (w , "loading applet" , http .StatusInternalServerError )
176
180
return
177
181
}
178
182
179
- w .Header ().Set ("Content-Type" , "image/webp" )
183
+ img_type := "image/webp"
184
+ if b .serveGif {
185
+ img_type = "image/gif"
186
+ }
187
+ w .Header ().Set ("Content-Type" , img_type )
180
188
181
- data , err := base64 .StdEncoding .DecodeString (webp )
189
+ data , err := base64 .StdEncoding .DecodeString (img )
182
190
if err != nil {
183
- http .Error (w , "decoding webp " , http .StatusInternalServerError )
191
+ http .Error (w , "decoding image " , http .StatusInternalServerError )
184
192
return
185
193
}
186
194
@@ -199,10 +207,15 @@ func (b *Browser) previewHandler(w http.ResponseWriter, r *http.Request) {
199
207
config [k ] = val [0 ]
200
208
}
201
209
202
- webp , err := b .loader .LoadApplet (config )
210
+ img , err := b .loader .LoadApplet (config )
211
+ img_type := "webp"
212
+ if b .serveGif {
213
+ img_type = "gif"
214
+ }
203
215
data := & previewData {
204
- WebP : webp ,
205
- Title : b .title ,
216
+ Image : img ,
217
+ ImageType : img_type ,
218
+ Title : b .title ,
206
219
}
207
220
if err != nil {
208
221
data .Err = err .Error ()
@@ -238,13 +251,19 @@ func (b *Browser) websocketHandler(w http.ResponseWriter, r *http.Request) {
238
251
}
239
252
240
253
func (b * Browser ) updateWatcher () error {
254
+ img_type := "webp"
255
+ if b .serveGif {
256
+ img_type = "gif"
257
+ }
258
+
241
259
for {
242
260
select {
243
261
case up := <- b .updateChan :
244
262
b .fo .Broadcast (
245
263
fanout.WebsocketEvent {
246
- Type : fanout .EventTypeWebP ,
247
- Message : up .WebP ,
264
+ Type : fanout .EventTypeImage ,
265
+ Message : up .Image ,
266
+ ImageType : img_type ,
248
267
},
249
268
)
250
269
@@ -279,12 +298,12 @@ func (b *Browser) oldRootHandler(w http.ResponseWriter, r *http.Request) {
279
298
config [k ] = vals [0 ]
280
299
}
281
300
282
- webp , err := b .loader .LoadApplet (config )
301
+ img , err := b .loader .LoadApplet (config )
283
302
284
303
data := previewData {
285
304
Title : b .title ,
286
305
Watch : b .watch ,
287
- WebP : webp ,
306
+ Image : img ,
288
307
}
289
308
290
309
if err != nil {
0 commit comments