Skip to content

Commit a276034

Browse files
author
‘ââyihua.luo
committed
submit code
1 parent 6cccc40 commit a276034

File tree

6 files changed

+195
-25
lines changed

6 files changed

+195
-25
lines changed

bin/www

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ app.set('port', port);
2121

2222
var server = http.createServer(app);
2323

24+
require('../server/socket.io/io').init(server);
25+
2426
/**
2527
* Listen on provided port, on all network interfaces.
2628
*/

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"express": "~4.13.1",
1414
"mongoose": "^4.4.15",
1515
"morgan": "~1.6.1",
16-
"serve-favicon": "~2.3.0"
16+
"serve-favicon": "~2.3.0",
17+
"socket.io": "^1.4.6"
1718
}
1819
}

public/js/main.js

+153-14
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,22 @@ String.prototype.startWith=function(str){
99
return true;
1010
}
1111

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+
1224
function resourceFactory(resourcePath){
1325

1426
var Resource = function(data){
15-
Object.assign(this, data);
27+
$.extend(this, data);
1628
};
1729
Resource.prototype.$data = function(){
1830
var pps = Object.getOwnPropertyNames(this);
@@ -31,6 +43,9 @@ function resourceFactory(resourcePath){
3143
return $.ajax({
3244
type: "post",
3345
url: resourcePath,
46+
headers: {
47+
uid: uid
48+
},
3449
data: data
3550
}).then(function(data){
3651
return new Resource(data);
@@ -43,6 +58,9 @@ function resourceFactory(resourcePath){
4358
return $.ajax({
4459
type: "PUT",
4560
url: resourcePath,
61+
headers: {
62+
uid: uid
63+
},
4664
data: data,
4765
}).then(function(data){
4866
return this;
@@ -52,16 +70,35 @@ function resourceFactory(resourcePath){
5270
Resource.prototype.$delete = function(){
5371
return $.ajax({
5472
type: "delete",
73+
headers: {
74+
uid: uid
75+
},
5576
url: resourcePath+'/'+this._id
5677
});
5778
};
5879

80+
function wrapper(list){
81+
return $.map(list, function(s){
82+
return new Resource(s);
83+
});
84+
}
85+
5986
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+
}
65102
});
66103
},
67104
model: Resource
@@ -70,17 +107,55 @@ function resourceFactory(resourcePath){
70107

71108
var TodoResource = resourceFactory('/api/todos');
72109

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+
73123
Vue.directive('datetimepicker', {
74124
bind: function () {
75-
$(this.el).datetimepicker();
125+
$(this.el).datetimepicker({
126+
minDate: new Date(),
127+
defaultDate: new Date(),
128+
step:5
129+
});
76130
},
77131
update: function (newValue, oldValue) {
78132

79133
},
80134
unbind: function () {
81135
$(this.el).datetimepicker('destroy');
82136
}
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+
});
84159

85160

86161
//{title: '', done: true, createDate: Date.now()}
@@ -95,7 +170,8 @@ var TodoItem = Vue.extend({
95170

96171
};
97172
}
98-
}
173+
},
174+
locale: String
99175
},
100176
data: function(){
101177
return {
@@ -134,6 +210,7 @@ var ColorPicker = Vue.extend({
134210

135211
var ItemAdd = Vue.extend({
136212
template: '#itemAdd',
213+
props: ['locale'],
137214
data: function(){
138215
return {
139216
showDialog: false,
@@ -203,6 +280,35 @@ var ItemAdd = Vue.extend({
203280
}
204281
});
205282

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+
206312
var Todo = Vue.extend({
207313
template: '#template',
208314
props: {
@@ -215,15 +321,18 @@ var Todo = Vue.extend({
215321
},
216322
data: function(){
217323
return {
218-
324+
locale: 'en'
219325
}
220326
},
221327
methods:{
222-
328+
selectThis: function(locale){
329+
this.locale = locale;
330+
}
223331
},
224332
components:{
225333
TodoItem: TodoItem,
226-
TodoAdd: ItemAdd
334+
TodoAdd: ItemAdd,
335+
NotificationAllow: NotificationAllow
227336
},
228337
events:{
229338
'item-remove': function(item){
@@ -235,22 +344,52 @@ var Todo = Vue.extend({
235344
'item-add': function(item){
236345
var self = this;
237346
new TodoResource.model(item).$save().then(function(resource){
347+
resource.remainTime = moment(resource.finishedTime).fromNow();
238348
self.list.push(resource);
239349
});
240350
}
241351
}
242352
});
243353

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+
244365
new Vue({
245366
el: '#app',
246367
data: {
247368
list: []
248369
},
249370
created:function(){
250371
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+
});
252377
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+
254393
},
255394
components:{
256395
Todo: Todo

server/controllers/todos.js

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
'use strict';
22

33
var Todos = require('../models/todos');
4+
var io = require('../socket.io/io');
5+
6+
function notifyAll(uid){
7+
Todos.find(function (err, todos) {
8+
io.update('todos', {
9+
uid: uid,
10+
data: todos
11+
});
12+
});
13+
}
414

515
exports.create = function (req, res) {
616
var todo = new Todos(req.body);
717

818
todo.save(function (err) {
919
res.json(todo);
20+
notifyAll(req.headers.uid);
1021
});
1122
};
1223

@@ -23,14 +34,14 @@ exports.update = function (req, res) {
2334
createDate: req.body.createDate
2435
}, {}, function (err, todo) {
2536
res.json(todo);
37+
notifyAll(req.headers.uid);
2638
});
2739
};
2840

2941
exports.remove = function (req, res) {
3042
console.log(req.params.id);
3143
Todos.findOneAndRemove({'_id': req.params.id}, function (err, todo) {
32-
console.log(err);
33-
console.log(todo);
3444
res.json(todo);
45+
notifyAll(req.headers.uid);
3546
});
3647
};

server/models/todos.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var Schema = mongoose.Schema;
66
var TodoSchema = new Schema({
77
title: String,
88
desc: String,
9-
finishedTime: Date,
9+
finishedTime: Number,
1010
color: String,
1111
done: {
1212
type: Boolean,

0 commit comments

Comments
 (0)