From abcaf058b8b98790687743736511bc2c28df430f Mon Sep 17 00:00:00 2001 From: Emmanuel Prochasson Date: Fri, 12 Jul 2013 12:38:58 +0800 Subject: [PATCH] Clean a bit of code. Start working on displaying conversation --- .meteor/packages | 4 +- TODO | 7 +- client/helpers/presence.js | 1 - client/helpers/router.js | 7 + client/main.js | 11 +- client/views/includes/loading.html | 3 + client/views/mailbox/conversation.html | 9 ++ client/views/mailbox/conversation.js | 7 + client/views/mailbox/mailbox.html | 12 +- client/views/mailbox/mailbox.js | 21 ++- client/views/widgets/online_friends.html | 2 +- client/views/widgets/online_friends.js | 5 +- main.config.js | 29 +++- server/fixtures.js | 196 ++++++++++++++++++++++- server/publications.js | 123 +++++++------- smart.json | 5 +- smart.lock | 24 ++- 17 files changed, 373 insertions(+), 93 deletions(-) create mode 100644 client/views/includes/loading.html create mode 100644 client/views/mailbox/conversation.html create mode 100644 client/views/mailbox/conversation.js diff --git a/.meteor/packages b/.meteor/packages index 8b344b0..989fafb 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -3,7 +3,6 @@ # 'meteor add' and 'meteor remove' will edit this file for you, # but you can also edit it by hand. -insecure preserve-inputs accounts-ui-bootstrap-dropdown bootstrap @@ -18,3 +17,6 @@ collectionFS imagemagick loadpicker page-js-ie-support +spin +publish-with-relations +paginated-subscription diff --git a/TODO b/TODO index 4e002a9..448706f 100644 --- a/TODO +++ b/TODO @@ -2,8 +2,11 @@ Make sure logout users are redirected to the front page, always. Browse users Setting page -Add a messaging system Activities: what did one do, what can of activity can the others see. -Check user security: do not allow user to change all their profile. \ No newline at end of file +Check user security: do not allow user to change all their profile. + + +myFriends and myOnlineFriends are redundant. Add pagination to myFriends, for the page that lists all friends. + diff --git a/client/helpers/presence.js b/client/helpers/presence.js index b6e536e..fa1a652 100644 --- a/client/helpers/presence.js +++ b/client/helpers/presence.js @@ -4,7 +4,6 @@ var presenceTick; Meteor.startup(function(){ // update presences every interval presenceTick = Meteor.setInterval(function() { - console.log('tick'); Meteor.Presence.update(); }, Presence.checkInterval || 1000); }); diff --git a/client/helpers/router.js b/client/helpers/router.js index 7132d7b..2b62223 100644 --- a/client/helpers/router.js +++ b/client/helpers/router.js @@ -11,6 +11,13 @@ Meteor.Router.add({ }, '/mailbox/compose': 'compose', '/mailbox': 'mailbox', + '/mailbox/:_id':{ + as: 'conversation', + to: 'conversation', + and: function(id){ + Session.set('currentConversation', id); + } + }, '/settings': 'settings', '/profile': { as: 'profile', diff --git a/client/main.js b/client/main.js index f46dc57..c50c3b6 100644 --- a/client/main.js +++ b/client/main.js @@ -9,11 +9,16 @@ Meteor.subscribe('myPictures'); Meteor.subscribe('myOnlineFriends'); // The list of my friends. -Meteor.subscribe('myFriends'); +Meteor.subscribe('myFriendList'); // My conversations -Meteor.subscribe('myConversations'); +conversationsHandle = Meteor.subscribeWithPagination('myConversations', 3); +var currentConversation = function(){ + return Session.get('currentConversation') || null; +}; + +oneConversationHandle = Meteor.subscribeWithPagination('oneConversation', currentConversation, 4); // When visiting someone's profile Deps.autorun(function () { @@ -23,3 +28,5 @@ Deps.autorun(function () { // Questions for the profile form. Meteor.subscribe('questions'); + +Meteor.subscribe('showFuckingEveryone'); diff --git a/client/views/includes/loading.html b/client/views/includes/loading.html new file mode 100644 index 0000000..c0b72b5 --- /dev/null +++ b/client/views/includes/loading.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/client/views/mailbox/conversation.html b/client/views/mailbox/conversation.html new file mode 100644 index 0000000..fd89ff6 --- /dev/null +++ b/client/views/mailbox/conversation.html @@ -0,0 +1,9 @@ + \ No newline at end of file diff --git a/client/views/mailbox/conversation.js b/client/views/mailbox/conversation.js new file mode 100644 index 0000000..cd92467 --- /dev/null +++ b/client/views/mailbox/conversation.js @@ -0,0 +1,7 @@ +Template.conversation.helpers({ + messages: function(){ + console.log('message'); + + return Messages.find({}, {sort: {timestamp: -1}}); + } +}); \ No newline at end of file diff --git a/client/views/mailbox/mailbox.html b/client/views/mailbox/mailbox.html index 9752a0e..282934c 100644 --- a/client/views/mailbox/mailbox.html +++ b/client/views/mailbox/mailbox.html @@ -1,11 +1,19 @@ \ No newline at end of file diff --git a/client/views/mailbox/mailbox.js b/client/views/mailbox/mailbox.js index c082399..19382fe 100644 --- a/client/views/mailbox/mailbox.js +++ b/client/views/mailbox/mailbox.js @@ -1,8 +1,25 @@ Template.mailbox.helpers({ conversations: function(){ - return Conversations.find({owner: Meteor.userId()}); + return Conversations.find({owner: Meteor.userId()},{limit: conversationsHandle.limit()}); + }, + conversationReady: function(){ + return ! conversationsHandle.loading(); + }, + allConversationsLoaded: function(){ + return !conversationsHandle.loading() && + Conversations.find({owner: Meteor.userId()}).count() < conversationsHandle.loaded() }, userInfo: function(){ - return this.with; + return Meteor.users.findOne(this.with); + }, + isMyFriend: function(){ + return _.contains(Meteor.user().friends, this.with); + } +}); + +Template.mailbox.events({ + 'click .load-more': function(e){ + e.preventDefault(); + conversationsHandle.loadNextPage(); } }); \ No newline at end of file diff --git a/client/views/widgets/online_friends.html b/client/views/widgets/online_friends.html index 45641c9..7b88a03 100644 --- a/client/views/widgets/online_friends.html +++ b/client/views/widgets/online_friends.html @@ -13,5 +13,5 @@ \ No newline at end of file diff --git a/client/views/widgets/online_friends.js b/client/views/widgets/online_friends.js index ffa93ab..68ec040 100644 --- a/client/views/widgets/online_friends.js +++ b/client/views/widgets/online_friends.js @@ -1,11 +1,10 @@ Template.online_friends.helpers({ friends: function(){ var friends = Meteor.user().friends || []; - return Meteor.users.find({'profile.online': 1, visible: 1, _id: {$in: friends}}); + return Meteor.users.find({'profile.online': 1, _id: {$in: friends}}); }, count: function(){ -// console.log(Meteor.user()); var friends = Meteor.user().friends || []; - return Meteor.users.find({'profile.online': 1, visible: 1, _id: {$in: friends}}).count(); + return Meteor.users.find({'profile.online': 1, _id: {$in: friends}}).count(); } }); \ No newline at end of file diff --git a/main.config.js b/main.config.js index c1446cc..70787a5 100644 --- a/main.config.js +++ b/main.config.js @@ -10,14 +10,39 @@ if(Meteor.isClient){ filePickerKey = "Av2HCAqJSM2aHdX5yKTZtz"; } +/* + Users + */ +// What fields are public for everyone +Meteor.user.publicProfileInformation = { + // show selected information + 'profile.name' : 1, + 'profile.dob': 1, + 'profile.gender': 1, + 'profile.online': 1, + 'profile.picture': 1 +}; +// What fields are reserved for friends only +Meteor.user.privateProfileInformation = { + 'profile': 1 // show all profile +}; + +// What field I can see about myself +Meteor.user.myProfileInformation = { + // show more information + 'profile': 1, + 'friends': 1, + 'settings': 1 +}; + + /* Messages */ // Duration to measure velocity (default 2 minutes). -//Messages.velocityCaliber = 60*1000*2; Messages.velocityCaliber = 30*1000; // If target user is online, how many messages per velocityCaliber millisecond can the emitter send -Messages.onlineMaxVelocity = 5; +Messages.onlineMaxVelocity = 15; // If target is offline Messages.offlineMaxVelocity = 5; // Cooldown penalty (def: 1 minute) diff --git a/server/fixtures.js b/server/fixtures.js index aadc150..979ec53 100644 --- a/server/fixtures.js +++ b/server/fixtures.js @@ -46,12 +46,65 @@ if(Questions.find().count() == 0){ required: true }); } -if(Meteor.users.find({}).count() <= 2){ +if(Meteor.users.find({}).count() <= 4){ +// Meteor.users.insert({ +// "createdAt": 1372216131137, +// "emails": [ +// { +// "address": "whatever", +// "verified": false +// } +// ], +// "friends": [ +// "L7SLCm9mJyetnb3oD" +// ], +// "invisible": false, +// "lastseen": 1373524657763, +// "online": 1, +// "profile": { +// "dob": "08-11-1982", +// "gender": "Female", +// "name": "Fake User 1", +// "online": 0 +// }, +// "services": { +// }, +// "settings": { +// "invisible": false +// }, +// "visible": 1 +// }); +// Meteor.users.insert({ +// "createdAt": 1372216131137, +// "emails": [ +// { +// "address": "whatever2", +// "verified": false +// } +// ], +// "friends": [ +// "L7SLCm9mJyetnb3oD" +// ], +// "invisible": false, +// "lastseen": 1373524657763, +// "online": 1, +// "profile": { +// "dob": "08-11-1992", +// "gender": "Male", +// "name": "Fake User 2", +// "online": 0 +// }, +// "services": { }, +// "settings": { +// "invisible": false +// }, +// "visible": 1 +// }); Meteor.users.insert({ "createdAt": 1372216131137, "emails": [ { - "address": "whatever", + "address": "3", "verified": false } ], @@ -62,13 +115,64 @@ if(Meteor.users.find({}).count() <= 2){ "lastseen": 1373524657763, "online": 1, "profile": { - "dob": "08-11-1982", + "dob": "08-11-1992", + "gender": "Male", + "name": "Fake User 3", + "online": 0 + }, + "services": { }, + "settings": { + "invisible": false + }, + "visible": 1 + }); + Meteor.users.insert({ + "createdAt": 1372216131137, + "emails": [ + { + "address": "4", + "verified": false + } + ], + "friends": [ + "L7SLCm9mJyetnb3oD" + ], + "invisible": false, + "lastseen": 1373524657763, + "online": 1, + "profile": { + "dob": "08-11-1992", "gender": "Female", - "name": "Fake User 1", + "name": "Fake User 4", "online": 0 }, - "services": { + "services": { }, + "settings": { + "invisible": false }, + "visible": 1 + }); + Meteor.users.insert({ + "createdAt": 1372216131137, + "emails": [ + { + "address": "5", + "verified": false + } + ], + "friends": [ + "L7SLCm9mJyetnb3oD" + ], + "invisible": false, + "lastseen": 1373524657763, + "online": 1, + "profile": { + "dob": "08-11-1992", + "gender": "Female", + "name": "Fake User 5", + "online": 0 + }, + "services": { }, "settings": { "invisible": false }, @@ -78,7 +182,7 @@ if(Meteor.users.find({}).count() <= 2){ "createdAt": 1372216131137, "emails": [ { - "address": "whatever2", + "address": "6", "verified": false } ], @@ -91,7 +195,85 @@ if(Meteor.users.find({}).count() <= 2){ "profile": { "dob": "08-11-1992", "gender": "Male", - "name": "Fake User 2", + "name": "Fake User 6", + "online": 0 + }, + "services": { }, + "settings": { + "invisible": false + }, + "visible": 1 + }); + Meteor.users.insert({ + "createdAt": 1372216131137, + "emails": [ + { + "address": "7", + "verified": false + } + ], + "friends": [ + "L7SLCm9mJyetnb3oD" + ], + "invisible": false, + "lastseen": 1373524657763, + "online": 1, + "profile": { + "dob": "08-11-1992", + "gender": "Female", + "name": "Fake User 7", + "online": 0 + }, + "services": { }, + "settings": { + "invisible": false + }, + "visible": 1 + }); + Meteor.users.insert({ + "createdAt": 1372216131137, + "emails": [ + { + "address": "8", + "verified": false + } + ], + "friends": [ + "L7SLCm9mJyetnb3oD" + ], + "invisible": false, + "lastseen": 1373524657763, + "online": 1, + "profile": { + "dob": "08-11-1992", + "gender": "Male", + "name": "Fake User 8", + "online": 0 + }, + "services": { }, + "settings": { + "invisible": false + }, + "visible": 1 + }); + Meteor.users.insert({ + "createdAt": 1372216131137, + "emails": [ + { + "address": "9", + "verified": false + } + ], + "friends": [ + "L7SLCm9mJyetnb3oD" + ], + "invisible": false, + "lastseen": 1373524657763, + "online": 1, + "profile": { + "dob": "08-11-1992", + "gender": "Female", + "name": "Fake User 9", "online": 0 }, "services": { }, diff --git a/server/publications.js b/server/publications.js index b9d5530..b55a839 100644 --- a/server/publications.js +++ b/server/publications.js @@ -2,13 +2,7 @@ Meteor.publish("myData", function () { return Meteor.users.find( {_id: this.userId}, - {fields: - { - profile: 1, - friends: 1, - settings: 1 - } - } + { fields: Meteor.user.myProfileInformation } ); }); @@ -17,67 +11,73 @@ Meteor.publish('questions', function(){ return Questions.find(); }); -//Meteor.publish("myConversations", function() { -// Meteor.publishWithRelations({ -// handle: this, -// collection: Conversations, -// filter: {owner: this.userId}, -// mappings: [{ -// key: 'with', -// collection: Meteor.users -// }] -// }); -//}); -// -//Meteor.publish("myConversations", function(limit, skip){ -// // We need basic information about the people we're talking to. -// var self = this, conversationsHandle = null, profileHandle = []; -// -// function publishProfile(conversation){ -//// console.log('conversation', conversation); -// var profile = Meteor.users.find(conversation.with); -// profileHandle[conversation._id] = profile.observe({ -// added: function(profile){ -// self.added(profile); -// } -// }); -// } -// conversationsHandle = Conversations.find({}, {limit: limit, skip: skip}).observe({ -//// conversationsHandle = Conversations.find({owner: this.userId}, {limit: limit, skip: skip}).observe({ -// added: function(conversation){ -//// publishProfile(conversation); -// self.added(conversation); -// } -// -// }); -// -// self.ready(); -// -// self.onStop(function(){ -// conversationsHandle.stop(); -// _.each(profileHandle, function(p){ p.stop()}); -// }); -//}); - -Meteor.publish("myConversations", function(limit, skip){ - return Conversations.find({owner: this.userId}, {limit: limit, skip: skip}); +Meteor.publish("myConversations", function(limit) { + Meteor.publishWithRelations({ + handle: this, + collection: Conversations, + filter: {owner: this.userId}, + options: {limit: limit}, + mappings: [{ // Publish people sending message as well, as they might not be in your friendlist. + key: 'with', + collection: Meteor.users, + options: {fields: Meteor.user.publicProfileInformation} + }] + }); +}); + +Meteor.publish("oneConversation", function(conversation, limit){ + + if(!conversation){ + return []; + } + + var conv = Conversations.findOne(conversation); + console.log(conv); + return Messages.find({ + $or: [{from: conv.owner, to: conv.with},{from: conv.with, to: conv.owner}] + }); }); Meteor.publish("myMessages", function(limit, skip){ return Messages.find({ $or: { to: this.userId, from: this.userId}}, {limit: limit, skip: skip}); }); -Meteor.publish("myFriends", function(limit, skip){ + +Meteor.publish("myFriendList", function(){ + // load a very light version of the friendlist var me = Meteor.users.findOne(this.userId); - return Meteor.users.find({_id : {$in : me.friends}}, {fields: { profile: 1 } }); + return Meteor.users.find( + {_id : {$in : me.friends}, 'visible': 1}, + { + sort: {'profile.name': 1}, + fields: {'profile.name': 1, _id: 1, 'profile.picture': 1} + } + ); +}); + +// Remove! +Meteor.publish("showFuckingEveryone", function(){ + var user = Meteor.users.findOne(this.userId); + if(user.isAdmin){ + return Meteor.users.find({}); + } else { + return []; + } }); // Also maintains user online/offline status Meteor.publish("myOnlineFriends", function(){ var friends = Meteor.users.findOne(this.userId).friends || []; - return Meteor.users.find({ 'profile.online': 1, 'settings.invisible': false, _id: {$in: friends}}, {sort: {lastConnected : -1}}); + return Meteor.users.find( + { 'profile.online': 1, 'visible': 1, 'settings.invisible': false, _id: {$in: friends}}, + { + sort: {lastConnected : -1}, + fields: Meteor.user.privateProfileInformation + } + ); }); + Meteor.publish("userProfile", function(userId){ // Check that this user can see each others. var source = Meteor.users.findOne(this.userId); @@ -88,27 +88,18 @@ Meteor.publish("userProfile", function(userId){ var fields = {}; if(target && target.blacklist && _.contains(target.blacklist ,source._id)){ // You're blocked - fields = { - 'profile.name': 1, - 'profile.gender': 1 - }; + fields = Meteor.users.publicProfileInformation; } else if(target.friends && _.contains(target.friends, source._id)){ // You're friends // show all profile. if(target.friends && _.contains(target.friends, source._id)){ - fields = { - 'profile': 1 - } + fields = Meteor.users.privateProfileInformation; } } else { - fields = { - 'profile.name': 1, - 'profile.gender': 1 - }; + fields = Meteor.users.publicProfileInformation; } return Meteor.users.find({_id: userId}, {fields: fields}); }); - Meteor.publish('oneUserPictures', function(userId){ if(userId){ // Send over the picture attached to a user depending on permission. diff --git a/smart.json b/smart.json index a7e8be8..36a5da1 100644 --- a/smart.json +++ b/smart.json @@ -11,6 +11,9 @@ "collectionFS": {}, "imagemagick": {}, "loadpicker": {}, - "publish-with-relations": {} + "publish-with-relations": {}, + "spin": {}, + "paginated-subscription": {}, + "pagination": {} } } diff --git a/smart.lock b/smart.lock index f85b0f3..86fa918 100644 --- a/smart.lock +++ b/smart.lock @@ -13,7 +13,10 @@ "collectionFS": {}, "imagemagick": {}, "loadpicker": {}, - "publish-with-relations": {} + "publish-with-relations": {}, + "spin": {}, + "paginated-subscription": {}, + "pagination": {} }, "packages": { "accounts-ui-bootstrap-dropdown": { @@ -23,8 +26,8 @@ }, "router": { "git": "https://github.com/tmeasday/meteor-router.git", - "tag": "v0.5.2", - "commit": "45af76a97624f141e4a61298d5a049e6adbb631c" + "tag": "v0.5.3", + "commit": "7bd3a1bdd1099625bb8b49406d9b8f961d6f4a17" }, "i18n": { "git": "https://github.com/jerico-dev/meteor-i18n.git", @@ -56,6 +59,21 @@ "tag": "v0.1.5", "commit": "98213e9f056b139597c99fb9ec2884ae6be76d91" }, + "spin": { + "git": "https://github.com/SachaG/meteor-spin.git", + "tag": "v0.2.0", + "commit": "fd3a2871a69442848b4b4e74f5e1ae28fa4a95a4" + }, + "paginated-subscription": { + "git": "https://github.com/tmeasday/meteor-paginated-subscription.git", + "tag": "v0.1.2", + "commit": "35e0c6112df2b4cfeb60b559276a93cac5ee2dd6" + }, + "pagination": { + "git": "https://github.com/egtann/meteor-pagination.git", + "tag": "v1.0.0", + "commit": "df546295d4bf11a89e57198c8074aa812d85755c" + }, "page-js-ie-support": { "git": "https://github.com/tmeasday/meteor-page-js-ie-support.git", "tag": "v1.3.5",