From 45ddd0fbe1d5c4820a270e562a1d33b6500f4776 Mon Sep 17 00:00:00 2001 From: Charlie DeTar Date: Fri, 12 Dec 2014 11:16:47 -0700 Subject: [PATCH 1/5] Remove now-obsolete title from page controller Title is set via ``PostPageController.getTitle`` in https://github.com/TelescopeJS/Telescope/blob/master/lib/router/filters.js#L170 --- client/views/posts/post_page.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/views/posts/post_page.js b/client/views/posts/post_page.js index 3cf622398..bb0102e54 100644 --- a/client/views/posts/post_page.js +++ b/client/views/posts/post_page.js @@ -15,6 +15,4 @@ Template[getTemplate('post_page')].helpers({ Template[getTemplate('post_page')].rendered = function(){ $('body').scrollTop(0); - if(this.data) // XXX - document.title = $(".post-title").text(); }; From 2a316ea7983e90a0d3def06c9198f58252efe5ed Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Sat, 13 Dec 2014 11:58:47 +0900 Subject: [PATCH 2/5] fix sign-out route --- client/views/users/sign_out.html | 5 +++++ i18n/en.i18n.json | 1 + lib/router/users.js | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 client/views/users/sign_out.html diff --git a/client/views/users/sign_out.html b/client/views/users/sign_out.html new file mode 100644 index 000000000..e2d8aadcf --- /dev/null +++ b/client/views/users/sign_out.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 250416bb5..2b16665b1 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -253,6 +253,7 @@ "posted_time": "Posted Time", "profile": "Profile", "sign_out": "Sign Out", + "you_ve_been_signed_out": "You've been signed out. Come back soon!", "invitedcount": "InvitedCount", "invites": "Invites", "invited": "Invited?", diff --git a/lib/router/users.js b/lib/router/users.js index c361c39ae..46ed7d007 100644 --- a/lib/router/users.js +++ b/lib/router/users.js @@ -44,10 +44,11 @@ Meteor.startup(function () { Router.route('/sign-out', { name: 'signOut', + template: getTemplate('sign_out'), onBeforeAction: function() { Meteor.logout(function() { - return Router.go('/'); }); + this.next(); } }); From 1b3bc168e1140dc757a43bc2a2818e3ac449c73c Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Sat, 13 Dec 2014 12:01:41 +0900 Subject: [PATCH 3/5] override Meteor.absoluteUrl() with URL provided in settings --- collections/settings.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/collections/settings.js b/collections/settings.js index d2658b820..924bb3fd5 100644 --- a/collections/settings.js +++ b/collections/settings.js @@ -328,4 +328,9 @@ if (Meteor.isClient){ setLanguage(fields.language) } }); -} \ No newline at end of file +} + +// override Meteor.absoluteUrl() with URL provided in settings +Meteor.startup(function () { + Meteor.absoluteUrl.defaultOptions.rootUrl = getSetting('siteUrl', Meteor.absoluteUrl()); +}); \ No newline at end of file From 1eb72079b49ebcb61c095bfb42ce2185c7faeea6 Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Sat, 13 Dec 2014 14:02:45 +0900 Subject: [PATCH 4/5] adding userCreatedCallbacks callback hook and refactoring user creation --- History.md | 5 ++ collections/settings.js | 12 +++- i18n/en.i18n.json | 1 + lib/debug.js | 4 ++ lib/users.js | 4 -- packages/telescope-base/lib/base.js | 12 ++-- packages/telescope-base/package.js | 1 + packages/telescope-email/lib/server/email.js | 19 ++++- packages/telescope-invites/lib/invites.js | 32 ++++++++- .../telescope-newsletter/lib/newsletter.js | 26 ++++++- .../lib/server/mailchimp.js | 13 ++-- .../lib/notifications.js | 15 +++- server/users.js | 70 ++++--------------- 13 files changed, 140 insertions(+), 74 deletions(-) create mode 100644 lib/debug.js diff --git a/History.md b/History.md index 106194de5..b8a0969fe 100644 --- a/History.md +++ b/History.md @@ -1,3 +1,8 @@ +* Added new `userCreatedCallbacks` callback hook. +* Added new `debug` setting. +* `siteUrl` setting now affects `Meteor.absoluteUrl()`. +* Added new `clog` function that only logs if `debug` setting is true. + ## v0.10.0 “RefactorScope” * Renaming Errors to Messages (thanks @yourcelf!). diff --git a/collections/settings.js b/collections/settings.js index 924bb3fd5..0eae0a46b 100644 --- a/collections/settings.js +++ b/collections/settings.js @@ -294,6 +294,15 @@ settingsSchemaObject = { private: true } }, + debug: { + type: Boolean, + optional: true, + label: 'Debug Mode', + autoform: { + group: 'debug', + instructions: 'Enable debug mode for more details console logs' + } + } }; // add any extra properties to settingsSchemaObject (provided by packages for example) @@ -330,7 +339,8 @@ if (Meteor.isClient){ }); } -// override Meteor.absoluteUrl() with URL provided in settings Meteor.startup(function () { + // override Meteor.absoluteUrl() with URL provided in settings Meteor.absoluteUrl.defaultOptions.rootUrl = getSetting('siteUrl', Meteor.absoluteUrl()); + debug = getSetting('debug', false); }); \ No newline at end of file diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 2b16665b1..fe2c493d1 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -51,6 +51,7 @@ "extraCode": "Extra Code", "emailFooter": "Email Footer", "notes": "Notes", + "debug": "Debug Mode" // Settings Fieldsets "general": "General", diff --git a/lib/debug.js b/lib/debug.js new file mode 100644 index 000000000..9e4f3457a --- /dev/null +++ b/lib/debug.js @@ -0,0 +1,4 @@ +clog = function (s) { + if(getSetting('debug', false)) + console.log(s); +} \ No newline at end of file diff --git a/lib/users.js b/lib/users.js index 5ae5957b4..5c155adf3 100644 --- a/lib/users.js +++ b/lib/users.js @@ -6,10 +6,6 @@ isAdmin=function(user){ user = (typeof user === 'undefined') ? Meteor.user() : user; return !!user && !!user.isAdmin; }; -setAdmin = function(user, admin){ - user = (typeof user === 'undefined') ? Meteor.user() : user; - user.isAdmin = !!admin; -}; updateAdmin = function(userId, admin) { Meteor.users.update(userId, {$set: {isAdmin: admin}}); }; diff --git a/packages/telescope-base/lib/base.js b/packages/telescope-base/lib/base.js index 602e4cd99..218af73e3 100644 --- a/packages/telescope-base/lib/base.js +++ b/packages/telescope-base/lib/base.js @@ -243,6 +243,11 @@ commentEditClientCallbacks = []; commentEditMethodCallbacks = []; // not used yet commentAfterEditMethodCallbacks = []; // not used yet +userEditRenderedCallbacks = []; +userEditClientCallbacks = []; +userCreatedCallbacks = []; +userProfileCompleteChecks = []; + // ------------------------------------- User Profiles -------------------------------- // userProfileDisplay = [ @@ -275,14 +280,11 @@ userProfileEdit = [ } ] -userEditRenderedCallbacks = []; -userEditClientCallbacks = []; - -userProfileCompleteChecks = [ +userProfileCompleteChecks.push( function(user) { return !!getEmail(user) && !!getUserName(user); } -]; +); // ------------------------------ Dynamic Templates ------------------------------ // diff --git a/packages/telescope-base/package.js b/packages/telescope-base/package.js index a3886fb86..8e250a938 100644 --- a/packages/telescope-base/package.js +++ b/packages/telescope-base/package.js @@ -57,6 +57,7 @@ Package.onUse(function (api) { 'userProfileCompleteChecks', 'userProfileDisplay', 'userProfileEdit', + 'userCreatedCallbacks', 'getTemplate', 'templates', diff --git a/packages/telescope-email/lib/server/email.js b/packages/telescope-email/lib/server/email.js index 53d1ec010..c1a302e83 100644 --- a/packages/telescope-email/lib/server/email.js +++ b/packages/telescope-email/lib/server/email.js @@ -92,4 +92,21 @@ Meteor.methods({ var email = buildAndSendEmail (getSetting('defaultEmail'), 'Telescope email test', 'emailTest', {date: new Date()}); } } -}) \ No newline at end of file +}) + +function adminUserCreationNotification (user) { + // send notifications to admins + var admins = adminUsers(); + admins.forEach(function(admin){ + if(getUserSetting('notifications.users', false, admin)){ + var emailProperties = { + profileUrl: getProfileUrl(user), + username: getUserName(user) + }; + var html = getEmailTemplate('emailNewUser')(emailProperties); + sendEmail(getEmail(admin), 'New user account: '+getUserName(user), buildEmailTemplate(html)); + } + }); + return user; +} +userCreatedCallbacks.push(adminUserCreationNotification); \ No newline at end of file diff --git a/packages/telescope-invites/lib/invites.js b/packages/telescope-invites/lib/invites.js index 167139e19..e237bb611 100644 --- a/packages/telescope-invites/lib/invites.js +++ b/packages/telescope-invites/lib/invites.js @@ -31,4 +31,34 @@ Invites.deny({ userProfileEdit.push({ template: 'userInvites', order: 2 -}); \ No newline at end of file +}); + + function setStartingInvites (user) { + // give new users a few invites (default to 3) + user.inviteCount = getSetting('startInvitesCount', 3); + return user; +} +userCreatedCallbacks.push(setStartingInvites); + +function checkIfInvited (user) { + // if the new user has been invited + // set her status accordingly and update invitation info + if(invitesEnabled() && getEmail(user)){ + var invite = Invites.findOne({ invitedUserEmail : getEmail(user) }); + if(invite){ + var invitedBy = Meteor.users.findOne({ _id : invite.invitingUserId }); + + user = _.extend(user, { + isInvited: true, + invitedBy: invitedBy._id, + invitedByName: getDisplayName(invitedBy) + }); + + Invites.update(invite._id, {$set : { + accepted : true + }}); + } + } + return user; +} +userCreatedCallbacks.push(checkIfInvited); diff --git a/packages/telescope-newsletter/lib/newsletter.js b/packages/telescope-newsletter/lib/newsletter.js index 7572d5c27..b3f599d0a 100644 --- a/packages/telescope-newsletter/lib/newsletter.js +++ b/packages/telescope-newsletter/lib/newsletter.js @@ -134,6 +134,19 @@ var newsletterFrequency = { } addToSettingsSchema.push(newsletterFrequency); +var autoSubscribe = { + propertyName: 'autoSubscribe', + propertySchema: { + type: Boolean, + optional: true, + autoform: { + group: 'newsletter', + instructions: 'Automatically subscribe new users on sign-up.' + } + } +} +addToSettingsSchema.push(autoSubscribe); + // create new "campaign" lens for all posts from the past X days that haven't been scheduled yet viewParameters.campaign = function (terms) { return { @@ -149,4 +162,15 @@ viewParameters.campaign = function (terms) { heroModules.push({ template: 'newsletterBanner' -}); \ No newline at end of file +}); + + function subscribeUserOnCreation (user) { + if (!!getSetting('autoSubscribe') && !!getEmail(user)) { + addToMailChimpList(user, false, function (error, result) { + console.log(error) + console.log(result) + }); + } + return user; +} +userCreatedCallbacks.push(subscribeUserOnCreation); diff --git a/packages/telescope-newsletter/lib/server/mailchimp.js b/packages/telescope-newsletter/lib/server/mailchimp.js index 46de3b79b..fdb39c0f1 100644 --- a/packages/telescope-newsletter/lib/server/mailchimp.js +++ b/packages/telescope-newsletter/lib/server/mailchimp.js @@ -78,12 +78,15 @@ scheduleCampaign = function (campaign, isTest) { } addToMailChimpList = function(userOrEmail, confirm, done){ + var user, email; - if(typeof userOrEmail == "string"){ + var confirm = (typeof confirm === 'undefined') ? false : confirm // default to no confirmation + + if (typeof userOrEmail == "string") { user = null; email = userOrEmail; - }else if(typeof userOrEmail == "object"){ + } else if (typeof userOrEmail == "object") { user = userOrEmail; email = getEmail(user); if (!email) @@ -100,16 +103,16 @@ addToMailChimpList = function(userOrEmail, confirm, done){ try { var api = new MailChimp(); - } catch ( error ) { + } catch (error) { console.log( error.message ); } - api.call( 'lists', 'subscribe', { + api.call('lists', 'subscribe', { id: MailChimpOptions.listId, email: {"email": email}, double_optin: confirm }, Meteor.bindEnvironment(function ( error, result ) { - if ( error ) { + if (error) { console.log( error.message ); done(error, null); } else { diff --git a/packages/telescope-notifications/lib/notifications.js b/packages/telescope-notifications/lib/notifications.js index 56c65dd2f..460cd78cb 100644 --- a/packages/telescope-notifications/lib/notifications.js +++ b/packages/telescope-notifications/lib/notifications.js @@ -63,4 +63,17 @@ var emailNotifications = { } } } -addToSettingsSchema.push(emailNotifications); \ No newline at end of file +addToSettingsSchema.push(emailNotifications); + + +function setNotificationDefaults (user) { + // set notifications default preferences + user.profile.notifications = { + users: false, + posts: false, + comments: true, + replies: true + }; + return user; +} +userCreatedCallbacks.push(setNotificationDefaults); \ No newline at end of file diff --git a/server/users.js b/server/users.js index 0c6e4c3c7..7d030c5df 100644 --- a/server/users.js +++ b/server/users.js @@ -15,78 +15,38 @@ Accounts.onCreateUser(function(options, user){ }; user = _.extend(user, userProperties); + // set email on profile if (options.email) user.profile.email = options.email; + // if email is set, use it to generate email hash if (getEmail(user)) user.email_hash = getEmailHash(user); + // set username on profile if (!user.profile.name) user.profile.name = user.username; - - // set notifications default preferences - user.profile.notifications = { - users: false, - posts: false, - comments: true, - replies: true - }; // create slug from username user.slug = slugify(getUserName(user)); // if this is the first user ever, make them an admin - if (!Meteor.users.find().count() ) { - setAdmin(user, true); - } else { - setAdmin(user, false); - } + user.isAdmin = Meteor.users.find().count() === 0 ? true : false; - // give new users a few invites (default to 3) - user.inviteCount = getSetting('startInvitesCount', 3); + // ------------------------------ Callbacks ------------------------------ // + + // run all post submit client callbacks on properties object successively + clog('// Start userCreatedCallbacks') + user = userCreatedCallbacks.reduce(function(result, currentFunction) { + clog('// Running '+currentFunction.name+'…') + return currentFunction(result); + }, user); + clog('// Finished userCreatedCallbacks') + clog('// User object:') + clog(user) trackEvent('new user', {username: user.username, email: user.profile.email}); - // if user has already filled in their email, add them to MailChimp list - // if(user.profile.email) - // addToMailChimpList(user, false, function(error, result){ - // if(error){ - // console.log(error) - // } - // }); - - // if the new user has been invited - // set her status accordingly and update invitation info - if(invitesEnabled() && user.profile.email){ - var invite = Invites.findOne({ invitedUserEmail : user.profile.email }); - if(invite){ - var invitedBy = Meteor.users.findOne({ _id : invite.invitingUserId }); - - user = _.extend(user, { - isInvited: true, - invitedBy: invitedBy._id, - invitedByName: getDisplayName(invitedBy) - }); - - Invites.update(invite._id, {$set : { - accepted : true - }}); - } - } - - // send notifications to admins - var admins = adminUsers(); - admins.forEach(function(admin){ - if(getUserSetting('notifications.users', false, admin)){ - var emailProperties = { - profileUrl: getProfileUrl(user), - username: getUserName(user) - }; - var html = getEmailTemplate('emailNewUser')(emailProperties); - sendEmail(getEmail(admin), 'New user account: '+getUserName(user), buildEmailTemplate(html)); - } - }); - return user; }); From 512cc7707d9e8591ae618c645cd34af46324f214 Mon Sep 17 00:00:00 2001 From: Sacha Greif Date: Sat, 13 Dec 2014 16:29:31 +0900 Subject: [PATCH 5/5] typo fix --- i18n/en.i18n.json | 2 +- server/users.js | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index fe2c493d1..104db7759 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -51,7 +51,7 @@ "extraCode": "Extra Code", "emailFooter": "Email Footer", "notes": "Notes", - "debug": "Debug Mode" + "debug": "Debug Mode", // Settings Fieldsets "general": "General", diff --git a/server/users.js b/server/users.js index 7d030c5df..aa5816418 100644 --- a/server/users.js +++ b/server/users.js @@ -1,4 +1,7 @@ Accounts.onCreateUser(function(options, user){ + + // ------------------------------ Properties ------------------------------ // + var userProperties = { profile: options.profile || {}, karma: 0, @@ -45,6 +48,8 @@ Accounts.onCreateUser(function(options, user){ clog('// User object:') clog(user) + // ------------------------------ Analytics ------------------------------ // + trackEvent('new user', {username: user.username, email: user.profile.email}); return user;