@@ -9,10 +9,22 @@ String.prototype.startWith=function(str){
9
9
return true ;
10
10
}
11
11
12
+ function genUid ( ) {
13
+ return new Date ( ) . getTime ( ) + "" + Math . floor ( Math . random ( ) * 899 + 100 ) ;
14
+ }
15
+
16
+ var uid = genUid ( ) ;
17
+
18
+ var io = ( function initIO ( ) {
19
+ var socket = io . connect ( ) ;
20
+ socket . emit ( 'register' , { uid : uid } ) ;
21
+ return socket ;
22
+ } ) ( ) ;
23
+
12
24
function resourceFactory ( resourcePath ) {
13
25
14
26
var Resource = function ( data ) {
15
- Object . assign ( this , data ) ;
27
+ $ . extend ( this , data ) ;
16
28
} ;
17
29
Resource . prototype . $data = function ( ) {
18
30
var pps = Object . getOwnPropertyNames ( this ) ;
@@ -31,6 +43,9 @@ function resourceFactory(resourcePath){
31
43
return $ . ajax ( {
32
44
type : "post" ,
33
45
url : resourcePath ,
46
+ headers : {
47
+ uid : uid
48
+ } ,
34
49
data : data
35
50
} ) . then ( function ( data ) {
36
51
return new Resource ( data ) ;
@@ -43,6 +58,9 @@ function resourceFactory(resourcePath){
43
58
return $ . ajax ( {
44
59
type : "PUT" ,
45
60
url : resourcePath ,
61
+ headers : {
62
+ uid : uid
63
+ } ,
46
64
data : data ,
47
65
} ) . then ( function ( data ) {
48
66
return this ;
@@ -52,16 +70,35 @@ function resourceFactory(resourcePath){
52
70
Resource . prototype . $delete = function ( ) {
53
71
return $ . ajax ( {
54
72
type : "delete" ,
73
+ headers : {
74
+ uid : uid
75
+ } ,
55
76
url : resourcePath + '/' + this . _id
56
77
} ) ;
57
78
} ;
58
79
80
+ function wrapper ( list ) {
81
+ return $ . map ( list , function ( s ) {
82
+ return new Resource ( s ) ;
83
+ } ) ;
84
+ }
85
+
59
86
return {
60
- all : function ( ) {
61
- return $ . get ( resourcePath ) . then ( function ( ss ) {
62
- return $ . map ( ss , function ( s ) {
63
- return new Resource ( s ) ;
64
- } ) ;
87
+ all : function ( callback ) {
88
+ $ . ajax ( {
89
+ type : "get" ,
90
+ url : resourcePath ,
91
+ headers : {
92
+ uid : uid
93
+ }
94
+ } ) . then ( function ( list ) {
95
+ callback ( wrapper ( list ) ) ;
96
+ } ) ;
97
+
98
+ io . on ( resourcePath , function ( result ) {
99
+ if ( result . uid !== uid ) {
100
+ callback ( wrapper ( result . data ) ) ;
101
+ }
65
102
} ) ;
66
103
} ,
67
104
model : Resource
@@ -70,17 +107,55 @@ function resourceFactory(resourcePath){
70
107
71
108
var TodoResource = resourceFactory ( '/api/todos' ) ;
72
109
110
+ var i18nPlugin = {
111
+ install : function ( Vue , options ) {
112
+ var locale = { } ;
113
+ Vue . locale = function ( localeOpt ) {
114
+ locale = localeOpt ;
115
+ } ;
116
+
117
+ Vue . prototype . $i = function ( localeStr , key ) {
118
+ return locale [ localeStr ] && locale [ localeStr ] [ key ] ;
119
+ } ;
120
+ }
121
+ } ;
122
+
73
123
Vue . directive ( 'datetimepicker' , {
74
124
bind : function ( ) {
75
- $ ( this . el ) . datetimepicker ( ) ;
125
+ $ ( this . el ) . datetimepicker ( {
126
+ minDate : new Date ( ) ,
127
+ defaultDate : new Date ( ) ,
128
+ step :5
129
+ } ) ;
76
130
} ,
77
131
update : function ( newValue , oldValue ) {
78
132
79
133
} ,
80
134
unbind : function ( ) {
81
135
$ ( this . el ) . datetimepicker ( 'destroy' ) ;
82
136
}
83
- } )
137
+ } ) ;
138
+
139
+ Vue . use ( i18nPlugin ) ;
140
+
141
+ Vue . locale ( {
142
+ "en" : {
143
+ "Allow Notification" : "Allow Notification" ,
144
+ "Todo Tasks" : "Todo Tasks" ,
145
+ "Input the title" : "Input the title" ,
146
+ "Input the desc" : "Input the desc" ,
147
+ "Finished time" : "Finished time" ,
148
+ "Your browser not support this function." : "Your browser not support this function."
149
+ } ,
150
+ "zh" : {
151
+ "Allow Notification" : "允许推送" ,
152
+ "Todo Tasks" : "待办任务" ,
153
+ "Input the title" : "输入标题" ,
154
+ "Input the desc" : "输入描述" ,
155
+ "Finished time" : "结束时间" ,
156
+ "Your browser not support this function." : "你的浏览器不支持该功能。"
157
+ }
158
+ } ) ;
84
159
85
160
86
161
//{title: '', done: true, createDate: Date.now()}
@@ -95,7 +170,8 @@ var TodoItem = Vue.extend({
95
170
96
171
} ;
97
172
}
98
- }
173
+ } ,
174
+ locale : String
99
175
} ,
100
176
data : function ( ) {
101
177
return {
@@ -134,6 +210,7 @@ var ColorPicker = Vue.extend({
134
210
135
211
var ItemAdd = Vue . extend ( {
136
212
template : '#itemAdd' ,
213
+ props : [ 'locale' ] ,
137
214
data : function ( ) {
138
215
return {
139
216
showDialog : false ,
@@ -203,6 +280,35 @@ var ItemAdd = Vue.extend({
203
280
}
204
281
} ) ;
205
282
283
+ var NotificationAllow = Vue . extend ( {
284
+ template : '#notificationAllow' ,
285
+ props : {
286
+ locale : String
287
+ } ,
288
+ data : function ( ) {
289
+ var allow = Notification && Notification . permission === 'granted' ;
290
+ return {
291
+ allow : allow
292
+ }
293
+ } ,
294
+ methods : {
295
+ allowIt : function ( ) {
296
+ var self = this ;
297
+ if ( window . Notification ) {
298
+ Notification . requestPermission ( function ( r ) {
299
+ if ( r === 'granted' ) {
300
+ self . allow = true ;
301
+ } else {
302
+ self . allow = false ;
303
+ }
304
+ } ) ;
305
+ } else {
306
+ alert ( this . $i ( "Your browser not support this function." ) ) ;
307
+ }
308
+ }
309
+ }
310
+ } ) ;
311
+
206
312
var Todo = Vue . extend ( {
207
313
template : '#template' ,
208
314
props : {
@@ -215,15 +321,18 @@ var Todo = Vue.extend({
215
321
} ,
216
322
data : function ( ) {
217
323
return {
218
-
324
+ locale : 'en'
219
325
}
220
326
} ,
221
327
methods :{
222
-
328
+ selectThis : function ( locale ) {
329
+ this . locale = locale ;
330
+ }
223
331
} ,
224
332
components :{
225
333
TodoItem : TodoItem ,
226
- TodoAdd : ItemAdd
334
+ TodoAdd : ItemAdd ,
335
+ NotificationAllow : NotificationAllow
227
336
} ,
228
337
events :{
229
338
'item-remove' : function ( item ) {
@@ -235,22 +344,52 @@ var Todo = Vue.extend({
235
344
'item-add' : function ( item ) {
236
345
var self = this ;
237
346
new TodoResource . model ( item ) . $save ( ) . then ( function ( resource ) {
347
+ resource . remainTime = moment ( resource . finishedTime ) . fromNow ( ) ;
238
348
self . list . push ( resource ) ;
239
349
} ) ;
240
350
}
241
351
}
242
352
} ) ;
243
353
354
+ function notification ( item ) {
355
+ if ( window . Notification ) {
356
+ if ( Notification . permission === 'granted' ) {
357
+ var notification = new Notification ( item . title , {
358
+ body : item . desc ,
359
+ icon : '/img/todo.png'
360
+ } ) ;
361
+ }
362
+ }
363
+ }
364
+
244
365
new Vue ( {
245
366
el : '#app' ,
246
367
data : {
247
368
list : [ ]
248
369
} ,
249
370
created :function ( ) {
250
371
var self = this ;
251
- TodoResource . all ( ) . then ( function ( result ) {
372
+
373
+ TodoResource . all ( function ( result ) {
374
+ $ . each ( result , function ( ) {
375
+ this . remainTime = moment ( this . finishedTime ) . fromNow ( ) ;
376
+ } ) ;
252
377
self . list = result ;
253
- } )
378
+ } ) ;
379
+
380
+ setInterval ( function ( ) {
381
+ $ . each ( self . list , function ( i ) {
382
+ this . remainTime = moment ( this . finishedTime ) . fromNow ( ) ;
383
+
384
+ var a = moment ( this . finishedTime ) ;
385
+ var b = moment ( ) ;
386
+ if ( Math . abs ( a . diff ( b ) ) < 60 * 1000 && ! this . isNotified ) {
387
+ notification ( this ) ;
388
+ this . isNotified = true ;
389
+ }
390
+ } ) ;
391
+ } , 1000 ) ;
392
+
254
393
} ,
255
394
components :{
256
395
Todo : Todo
0 commit comments