1
1
const { h, render, Component } = preact ;
2
- const { Router, Link } = preactRouter ;
2
+ const { route , Router, Link } = preactRouter ;
3
3
4
4
const INITIAL_TEXT = `root:
5
5
- Dear {{ giver }}, thank you for the {{ object }}.
@@ -16,6 +16,11 @@ object:
16
16
- dishwasher
17
17
` ;
18
18
19
+ const GALLERY = [
20
+ '-L0iXXTIHpU3fd0hXiEo' ,
21
+ '-L0ibWrnaptySlFrOniw'
22
+ ] ;
23
+
19
24
let gApp ;
20
25
21
26
class Header extends Component {
@@ -29,21 +34,38 @@ class Header extends Component {
29
34
30
35
class Home extends Component {
31
36
render ( props , state ) {
37
+ const thumbs = GALLERY . map ( id => this . renderThumb ( id ) ) ;
38
+ console . log ( thumbs ) ;
32
39
return h ( 'div' , { class : 'app' } ,
33
40
h ( Header , { } ,
34
41
h ( Link , { class : 'button' , href : '/sketch' } , 'Create' )
35
42
) ,
36
43
h ( 'div' , { class : 'page' } ,
37
- h ( 'h1' , { } , 'Click the "create" button to create a new sketch.' )
44
+ h ( 'h1' , { } , 'Gallery' ) ,
45
+ h ( 'div' , { class : 'gallery' } ,
46
+ thumbs
47
+ )
48
+ )
49
+ ) ;
50
+ }
51
+
52
+ renderThumb ( id ) {
53
+ return h ( 'div' , { class : 'gallery__thumb' } ,
54
+ h ( Link , { class : 'gallery__link' , href : `/sketch/${ id } ` } ,
55
+ h ( 'img' , { class : 'gallery__img' , src : `/gallery/${ id } .png` } )
38
56
)
39
57
) ;
40
58
}
41
59
}
42
60
43
61
class Sketch extends Component {
44
- constructor ( ) {
45
- super ( ) ;
46
- this . state = { source : INITIAL_TEXT , debug : true , debugOutput : '' , result : '' } ;
62
+ constructor ( props ) {
63
+ super ( props ) ;
64
+ if ( ! props . id ) {
65
+ this . state = { source : INITIAL_TEXT , debug : true , debugOutput : '' , result : '' , unsaved : false } ;
66
+ } else {
67
+ this . state = { loading : true , source : '' , debug : true , debugOutput : '' , result : '' , unsaved : false } ;
68
+ }
47
69
gApp = this ;
48
70
}
49
71
@@ -59,30 +81,58 @@ class Sketch extends Component {
59
81
}
60
82
61
83
componentDidMount ( ) {
62
- this . generate ( ) ;
84
+ if ( ! this . props . id ) {
85
+ this . generate ( ) ;
86
+ } else {
87
+ console . log ( 'loading from database' , this . props . id ) ;
88
+ firebase . database ( ) . ref ( `sketch/${ this . props . id } ` ) . once ( 'value' , snap => {
89
+ const sketch = { key : this . props . id , ...snap . val ( ) } ;
90
+ this . setState ( { loading : false , source : sketch . source } ) ;
91
+ this . generate ( ) ;
92
+ } ) ;
93
+ }
94
+
95
+ window . addEventListener ( 'beforeunload' , ( e ) => {
96
+ let confirm = null ;
97
+ if ( this . state . unsaved ) {
98
+ confirm = 'You have unsaved changes.' ;
99
+ ( e || window . event ) . returnValue = confirm ;
100
+ }
101
+ return confirm ;
102
+ } ) ;
63
103
}
64
104
65
105
onInput ( e ) {
66
106
const source = e . target . value ;
67
- this . setState ( { source : e . target . value } ) ;
107
+ this . setState ( { unsaved : true , source } ) ;
68
108
this . generate ( ) ;
69
109
}
70
110
71
111
onSave ( ) {
72
- // FIXME: save the content
112
+ if ( this . state . saving ) return ;
113
+ this . setState ( { saving : true } ) ;
114
+ const ref = firebase . database ( ) . ref ( 'sketch' ) . push ( ) ;
115
+ ref . set ( {
116
+ source : this . state . source
117
+ } , ( ) => {
118
+ this . setState ( { saving : false , unsaved : false } ) ;
119
+ route ( `/sketch/${ ref . key } ` ) ;
120
+ } ) ;
73
121
}
74
122
75
123
render ( props , state ) {
76
124
const debugView = h ( 'pre' , { className : 'debug' } , this . state . debugOutput ) ;
125
+ const source = state . loading ? 'Loading...' : state . source ;
126
+ let saveLabel = state . saving ? 'Saving...' : 'Save' ;
77
127
return h ( 'div' , { class : 'app' } ,
78
128
h ( Header , { } ,
79
- h ( 'button' , { class : 'button' , onClick : this . onSave . bind ( this ) } , 'Save' )
129
+ h ( 'button' , { class : 'button' + ( state . unsaved ? ' unsaved' : '' ) , onClick : this . onSave . bind ( this ) , disabled : state . saving } , saveLabel )
80
130
) ,
81
131
h ( 'div' , { className : 'editor' } ,
82
132
h ( 'div' , { className : 'editor__toolbar' } , h ( 'button' , { class : 'button' , onClick : this . generate . bind ( this ) } , 'Generate' ) ) ,
83
133
h ( 'div' , { className : 'editor__panels' } ,
84
134
h ( 'div' , { className : 'editor__source' } ,
85
- h ( 'textarea' , { className : 'editor__area' , value : state . source , onInput : this . onInput . bind ( this ) } ) ,
135
+ h ( 'textarea' , { className : 'editor__area' , value : source , onInput : this . onInput . bind ( this ) , readonly : state . loading } ) ,
86
136
debugView
87
137
) ,
88
138
h ( 'div' , { className : 'editor__viewer' } ,
@@ -99,7 +149,8 @@ class NotFound extends Component {
99
149
return h ( 'div' , { class : 'app' } ,
100
150
h ( Header , { } ) ,
101
151
h ( 'div' , { class : 'page' } ,
102
- h ( 'h1' , { } , 'Page not found.' )
152
+ h ( 'h1' , { } , 'Page not found.' ) ,
153
+ h ( Link , { href : '/' } , 'Go Back Home' )
103
154
)
104
155
) ;
105
156
}
@@ -110,6 +161,7 @@ class App extends Component {
110
161
return h ( Router , { } ,
111
162
h ( Home , { path : '/' } ) ,
112
163
h ( Sketch , { path : '/sketch' } ) ,
164
+ h ( Sketch , { path : '/sketch/:id' } ) ,
113
165
h ( NotFound , { type : '404' , default : true } )
114
166
) ;
115
167
}
0 commit comments