Added global option + malformed email + cleaning
- Added 'panelDisplayLocation' option to choose where to show the subscription form - Manage malformed email (it crashed EPL) - Brought back popup form to subscribe (with the new options + unsubscription) - Popup form is a copy of the form in mysettings menu, so no more 2 html codes in 2 different places - On unsubscription, only remove the email from "globalAuthor" row if the email is the same. - Put all css styles in css file - Some cleaning
This commit is contained in:
parent
7d3d2a2920
commit
330cc427b8
10 changed files with 464 additions and 207 deletions
|
@ -11,6 +11,10 @@ NOTE: You will NOT receive an email if you(the author that registered their emai
|
||||||
|
|
||||||
```
|
```
|
||||||
"ep_email_notifications" : {
|
"ep_email_notifications" : {
|
||||||
|
panelDisplayLocation: { // Where you want to have the subscription panel
|
||||||
|
mysettings: true, // In the "mysettings" menu
|
||||||
|
popup: true // A popup that pop in the bottom right corner of the pad after 10 seconds
|
||||||
|
},
|
||||||
checkFrequency: 6000, // checkFrequency = How frequently(milliseconds) to check for pad updates -- Move me to the settings file
|
checkFrequency: 6000, // checkFrequency = How frequently(milliseconds) to check for pad updates -- Move me to the settings file
|
||||||
staleTime: 30000, // staleTime = How stale(milliseconds) does a pad need to be before notifying subscribers? Move me to settings
|
staleTime: 30000, // staleTime = How stale(milliseconds) does a pad need to be before notifying subscribers? Move me to settings
|
||||||
fromName: "Etherpad SETTINGS FILE!",
|
fromName: "Etherpad SETTINGS FILE!",
|
||||||
|
@ -27,5 +31,4 @@ NOTE: You will NOT receive an email if you(the author that registered their emai
|
||||||
|
|
||||||
# FUTURE VERSIONS TODO
|
# FUTURE VERSIONS TODO
|
||||||
* v2 - Get the modified contents from the API HTML diff and append that to the Email and make the email from the server HTML not plain text
|
* v2 - Get the modified contents from the API HTML diff and append that to the Email and make the email from the server HTML not plain text
|
||||||
* v2 - a point to unsubscribe and validate/verify email https://github.com/alfredwesterveld/node-email-verification
|
|
||||||
* v2 - Keep a record of when a user was last on a pad
|
* v2 - Keep a record of when a user was last on a pad
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
var eejs = require("ep_etherpad-lite/node/eejs");
|
var eejs = require("ep_etherpad-lite/node/eejs");
|
||||||
|
var settings = require('../../src/node/utils/Settings');
|
||||||
|
|
||||||
exports.eejsBlock_scripts = function (hook_name, args, cb) {
|
exports.eejsBlock_scripts = function (hook_name, args, cb) {
|
||||||
args.content = args.content + eejs.require("ep_email_notifications/templates/scripts.html", {}, module);
|
args.content = args.content + eejs.require("ep_email_notifications/templates/scripts.html", {}, module);
|
||||||
|
@ -13,3 +14,8 @@ exports.eejsBlock_mySettings = function (hook_name, args, cb) {
|
||||||
exports.eejsBlock_styles = function (hook_name, args, cb) {
|
exports.eejsBlock_styles = function (hook_name, args, cb) {
|
||||||
args.content = args.content + '<link href="../static/plugins/ep_email_notifications/static/css/email_notifications.css" rel="stylesheet">';
|
args.content = args.content + '<link href="../static/plugins/ep_email_notifications/static/css/email_notifications.css" rel="stylesheet">';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.clientVars = function(hook, context, callback) {
|
||||||
|
// return the setting to the clientVars, sending the value
|
||||||
|
return callback({ "panelDisplayLocation": settings.ep_email_notifications.panelDisplayLocation });
|
||||||
|
};
|
||||||
|
|
3
ep.json
3
ep.json
|
@ -7,7 +7,8 @@
|
||||||
"handleMessage": "ep_email_notifications/handleMessage",
|
"handleMessage": "ep_email_notifications/handleMessage",
|
||||||
"eejsBlock_scripts": "ep_email_notifications/client",
|
"eejsBlock_scripts": "ep_email_notifications/client",
|
||||||
"eejsBlock_mySettings": "ep_email_notifications/client:eejsBlock_mySettings",
|
"eejsBlock_mySettings": "ep_email_notifications/client:eejsBlock_mySettings",
|
||||||
"eejsBlock_styles": "ep_email_notifications/client:eejsBlock_styles"
|
"eejsBlock_styles": "ep_email_notifications/client:eejsBlock_styles",
|
||||||
|
"clientVars": "ep_email_notifications/client:clientVars"
|
||||||
},
|
},
|
||||||
"client_hooks": {
|
"client_hooks": {
|
||||||
"postAceInit":"ep_email_notifications/static/js/ep_email:postAceInit",
|
"postAceInit":"ep_email_notifications/static/js/ep_email:postAceInit",
|
||||||
|
|
350
handleMessage.js
350
handleMessage.js
|
@ -1,7 +1,6 @@
|
||||||
var db = require('../../src/node/db/DB').db,
|
var db = require('../../src/node/db/DB').db,
|
||||||
API = require('../../src/node/db/API.js'),
|
API = require('../../src/node/db/API.js'),
|
||||||
async = require('../../src/node_modules/async'),
|
async = require('../../src/node_modules/async'),
|
||||||
check = require('validator').check,
|
|
||||||
settings = require('../../src/node/utils/Settings');
|
settings = require('../../src/node/utils/Settings');
|
||||||
|
|
||||||
var pluginSettings = settings.ep_email_notifications;
|
var pluginSettings = settings.ep_email_notifications;
|
||||||
|
@ -14,16 +13,37 @@ exports.handleMessage = function(hook_name, context, callback){
|
||||||
if(context.message.data.userInfo.email){ // it contains email
|
if(context.message.data.userInfo.email){ // it contains email
|
||||||
console.debug(context.message);
|
console.debug(context.message);
|
||||||
|
|
||||||
// does email Subscription already exist for this email address?
|
// does email (Un)Subscription already exist for this email address?
|
||||||
db.get("emailSubscription:"+context.message.data.padId, function(err, userIds){
|
db.get("emailSubscription:"+context.message.data.padId, function(err, userIds){
|
||||||
|
|
||||||
var alreadyExists = false;
|
var alreadyExists = false;
|
||||||
|
|
||||||
if(userIds){
|
if(userIds){
|
||||||
async.forEach(Object.keys(userIds), function(user, cb){
|
async.forEach(Object.keys(userIds), function(user, cb){
|
||||||
console.debug("UserIds subscribed by email to this pad:", userIds);
|
console.debug("UserIds subscribed by email to this pad:", userIds);
|
||||||
if(user == context.message.data.userInfo.email){ // If we already have this email registered for this pad
|
if(user == context.message.data.userInfo.email){ // If we already have this email registered for this pad
|
||||||
// This user ID is already assigned to this padId so don't do anything except tell the user they are already subscribed somehow..
|
// This user ID is already assigned to this padId so don't do anything except tell the user they are already subscribed somehow..
|
||||||
alreadyExists = true;
|
alreadyExists = true;
|
||||||
|
|
||||||
|
if(context.message.data.userInfo.email_option == 'subscribe') {
|
||||||
|
// Subscription process
|
||||||
|
exports.subscriptionEmail(
|
||||||
|
context,
|
||||||
|
context.message.data.userInfo.email,
|
||||||
|
alreadyExists,
|
||||||
|
context.message.data.userInfo,
|
||||||
|
context.message.data.padId,
|
||||||
|
callback
|
||||||
|
);
|
||||||
|
} else if (context.message.data.userInfo.email_option == 'unsubscribe') {
|
||||||
|
// Unsubscription process
|
||||||
|
exports.unsubscriptionEmail(
|
||||||
|
context,
|
||||||
|
alreadyExists,
|
||||||
|
context.message.data.userInfo,
|
||||||
|
context.message.data.padId
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cb();
|
cb();
|
||||||
},
|
},
|
||||||
|
@ -33,116 +53,58 @@ exports.handleMessage = function(hook_name, context, callback){
|
||||||
}); // end async for each
|
}); // end async for each
|
||||||
}
|
}
|
||||||
|
|
||||||
if(context.message.data.userInfo.email_option == 'subscribe' && alreadyExists == true){
|
// In case we didn't find it in the Db
|
||||||
// SUbscription
|
if (alreadyExists == false) {
|
||||||
console.debug("email ", context.message.data.userInfo.email, "already subscribed to ", context.message.data.padId, " so sending message to client");
|
if(context.message.data.userInfo.email_option == 'subscribe') {
|
||||||
|
// Subscription process
|
||||||
context.client.json.send({ type: "COLLABROOM",
|
exports.subscriptionEmail(
|
||||||
data:{
|
context,
|
||||||
type: "emailSubscriptionSuccess",
|
context.message.data.userInfo.email,
|
||||||
payload: false
|
alreadyExists,
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if(context.message.data.userInfo.email_option == 'subscribe' && alreadyExists == false){
|
|
||||||
// SUbscription
|
|
||||||
var validatesAsEmail = check(context.message.data.userInfo.email).isEmail();
|
|
||||||
if(!validatesAsEmail){
|
|
||||||
// Subscription -> failed coz mail malformed.. y'know in general fuck em!
|
|
||||||
console.warn("Dropped email subscription due to malformed email address");
|
|
||||||
context.client.json.send({ type: "COLLABROOM",
|
|
||||||
data:{
|
|
||||||
type: "emailSubscriptionSuccess",
|
|
||||||
payload: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Subscription -> Go for it
|
|
||||||
console.debug ("Subscription: Wrote to the database and sent client a positive response ",context.message.data.userInfo.email);
|
|
||||||
|
|
||||||
exports.setAuthorEmail(
|
|
||||||
context.message.data.userInfo.userId,
|
|
||||||
context.message.data.userInfo,
|
context.message.data.userInfo,
|
||||||
|
context.message.data.padId,
|
||||||
callback
|
callback
|
||||||
);
|
);
|
||||||
|
} else if (context.message.data.userInfo.email_option == 'unsubscribe') {
|
||||||
exports.setAuthorEmailRegistered(
|
// Unsubscription process
|
||||||
|
exports.unsubscriptionEmail(
|
||||||
|
context,
|
||||||
|
alreadyExists,
|
||||||
context.message.data.userInfo,
|
context.message.data.userInfo,
|
||||||
context.message.data.userInfo.userId,
|
|
||||||
context.message.data.padId
|
context.message.data.padId
|
||||||
);
|
);
|
||||||
|
|
||||||
context.client.json.send({ type: "COLLABROOM",
|
|
||||||
data:{
|
|
||||||
type: "emailSubscriptionSuccess",
|
|
||||||
payload: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} else if(context.message.data.userInfo.email_option == 'unsubscribe' && alreadyExists == true) {
|
|
||||||
// Unsubscription -> Go for it
|
|
||||||
console.debug ("Unsubscription: Remove from the database and sent client a positive response ",context.message.data.userInfo.email);
|
|
||||||
|
|
||||||
exports.unsetAuthorEmail(
|
|
||||||
context.message.data.userInfo.userId,
|
|
||||||
context.message.data.userInfo,
|
|
||||||
callback
|
|
||||||
);
|
|
||||||
|
|
||||||
exports.unsetAuthorEmailRegistered(
|
|
||||||
context.message.data.userInfo,
|
|
||||||
context.message.data.userInfo.userId,
|
|
||||||
context.message.data.padId
|
|
||||||
);
|
|
||||||
|
|
||||||
context.client.json.send({ type: "COLLABROOM",
|
|
||||||
data:{
|
|
||||||
type: "emailUnsubscriptionSuccess",
|
|
||||||
payload: true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if(context.message.data.userInfo.email_option == 'unsubscribe' && alreadyExists == false) {
|
|
||||||
// Unsubscription -> Send failed as email not found
|
|
||||||
console.debug ("Unsubscription: Send client a negative response ",context.message.data.userInfo.email);
|
|
||||||
|
|
||||||
context.client.json.send({ type: "COLLABROOM",
|
|
||||||
data:{
|
|
||||||
type: "emailUnsubscriptionSuccess",
|
|
||||||
payload: false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}); // close db get
|
}); // close db get
|
||||||
|
|
||||||
callback([null]); // don't run onto passing colorId or anything else to the message handler
|
callback([null]); // don't run onto passing colorId or anything else to the message handler
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (context.message.data.type == 'USERINFO_GET' ) { // A request to find datas for a username
|
|
||||||
|
} else if (context.message.data.type == 'USERINFO_GET' ) { // A request to find datas for a userId
|
||||||
if (context.message.data.userInfo){
|
if (context.message.data.userInfo){
|
||||||
if(context.message.data.userInfo.userId){ // it contains the userId
|
if(context.message.data.userInfo.userId){ // it contains the userId
|
||||||
console.debug(context.message);
|
console.debug(context.message);
|
||||||
|
|
||||||
var userIdFound = false;
|
|
||||||
// does email Subscription already exist for this UserId?
|
// does email Subscription already exist for this UserId?
|
||||||
db.get("emailSubscription:"+context.message.data.padId, function(err, userIds){
|
db.get("emailSubscription:"+context.message.data.padId, function(err, userIds){
|
||||||
|
var userIdFound = false;
|
||||||
|
|
||||||
if(userIds){
|
if(userIds){
|
||||||
async.forEach(Object.keys(userIds), function(user, cb){
|
async.forEach(Object.keys(userIds), function(user, cb){
|
||||||
if(userIds[user].authorId == context.message.data.userInfo.userId){ // if we find the same Id in the Db as the one used by the user
|
if(userIds[user].authorId == context.message.data.userInfo.userId){ // if we find the same Id in the Db as the one used by the user
|
||||||
console.debug("Options for this pad ", userIds[user].authorId, " found in the Db");
|
console.debug("Options for this pad ", userIds[user].authorId, " found in the Db");
|
||||||
userIdFound = true;
|
userIdFound = true;
|
||||||
|
|
||||||
// We send back the options associated to this userId
|
// Request user subscription info process
|
||||||
context.client.json.send({ type: "COLLABROOM",
|
exports.sendUserInfo (
|
||||||
data:{
|
context,
|
||||||
type: "emailNotificationGetUserInfo",
|
userIdFound,
|
||||||
payload: {
|
user,
|
||||||
email: user,
|
userIds[user]
|
||||||
onStart: userIds[user].onStart && typeof userIds[user].onStart === 'boolean'?userIds[user].onStart:true,
|
);
|
||||||
onEnd: userIds[user].onEnd && typeof userIds[user].onEnd === 'boolean'?userIds[user].onEnd:false,
|
|
||||||
success:true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
cb();
|
cb();
|
||||||
},
|
},
|
||||||
|
@ -151,19 +113,19 @@ exports.handleMessage = function(hook_name, context, callback){
|
||||||
// There should be something in here!
|
// There should be something in here!
|
||||||
}); // end async for each
|
}); // end async for each
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userIdFound == false) {
|
||||||
|
// Request user subscription info process
|
||||||
|
exports.sendUserInfo (
|
||||||
|
context,
|
||||||
|
userIdFound,
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!userIdFound) {
|
callback([null]);
|
||||||
// No options set for this userId
|
|
||||||
context.client.json.send({ type: "COLLABROOM",
|
|
||||||
data:{
|
|
||||||
type: "emailNotificationGetUserInfo",
|
|
||||||
payload: {
|
|
||||||
success:false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -171,25 +133,189 @@ exports.handleMessage = function(hook_name, context, callback){
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subscription process
|
||||||
|
*/
|
||||||
|
exports.subscriptionEmail = function (context, email, emailFound, userInfo, padId, callback) {
|
||||||
|
var validatesAsEmail = exports.checkEmailValidation(email);
|
||||||
|
|
||||||
|
if(emailFound == false && validatesAsEmail){
|
||||||
|
// Subscription -> Go for it
|
||||||
|
console.debug ("Subscription: Wrote to the database and sent client a positive response ",context.message.data.userInfo.email);
|
||||||
|
|
||||||
|
exports.setAuthorEmail(
|
||||||
|
userInfo.userId,
|
||||||
|
userInfo,
|
||||||
|
callback
|
||||||
|
);
|
||||||
|
|
||||||
|
exports.setAuthorEmailRegistered(
|
||||||
|
userInfo,
|
||||||
|
userInfo.userId,
|
||||||
|
padId
|
||||||
|
);
|
||||||
|
|
||||||
|
context.client.json.send({ type: "COLLABROOM",
|
||||||
|
data:{
|
||||||
|
type: "emailSubscriptionSuccess",
|
||||||
|
payload: {
|
||||||
|
formName: userInfo.formName,
|
||||||
|
success: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (!validatesAsEmail) {
|
||||||
|
// Subscription -> failed coz mail malformed.. y'know in general fuck em!
|
||||||
|
console.warn("Dropped email subscription due to malformed email address");
|
||||||
|
context.client.json.send({ type: "COLLABROOM",
|
||||||
|
data:{
|
||||||
|
type: "emailSubscriptionSuccess",
|
||||||
|
payload: {
|
||||||
|
type: "malformedEmail",
|
||||||
|
formName: userInfo.formName,
|
||||||
|
success: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Subscription -> failed coz email already subscribed for this pad
|
||||||
|
console.debug("email ", context.message.data.userInfo.email, "already subscribed to ", context.message.data.padId, " so sending message to client");
|
||||||
|
|
||||||
|
context.client.json.send({ type: "COLLABROOM",
|
||||||
|
data:{
|
||||||
|
type: "emailSubscriptionSuccess",
|
||||||
|
payload: {
|
||||||
|
type: "alreadyRegistered",
|
||||||
|
formName: userInfo.formName,
|
||||||
|
success: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UnsUbscription process
|
||||||
|
*/
|
||||||
|
exports.unsubscriptionEmail = function (context, emailFound, userInfo, padId) {
|
||||||
|
if(emailFound == true) {
|
||||||
|
// Unsubscription -> Go for it
|
||||||
|
console.debug ("Unsubscription: Remove from the database and sent client a positive response ",context.message.data.userInfo.email);
|
||||||
|
|
||||||
|
exports.unsetAuthorEmail(
|
||||||
|
userInfo.userId,
|
||||||
|
userInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
exports.unsetAuthorEmailRegistered(
|
||||||
|
userInfo,
|
||||||
|
userInfo.userId,
|
||||||
|
padId
|
||||||
|
);
|
||||||
|
|
||||||
|
context.client.json.send({ type: "COLLABROOM",
|
||||||
|
data:{
|
||||||
|
type: "emailUnsubscriptionSuccess",
|
||||||
|
payload: {
|
||||||
|
formName: userInfo.formName,
|
||||||
|
success: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Unsubscription -> Send failed as email not found
|
||||||
|
console.debug ("Unsubscription: Send client a negative response ",context.message.data.userInfo.email);
|
||||||
|
|
||||||
|
context.client.json.send({ type: "COLLABROOM",
|
||||||
|
data:{
|
||||||
|
type: "emailUnsubscriptionSuccess",
|
||||||
|
payload: {
|
||||||
|
formName: userInfo.formName,
|
||||||
|
success: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request user subscription info process
|
||||||
|
*/
|
||||||
|
exports.sendUserInfo = function (context, emailFound, email, userInfo) {
|
||||||
|
var defaultOnStartOption = true;
|
||||||
|
var defaultOnEndOption = false;
|
||||||
|
|
||||||
|
if (typeof userInfo.onStart == 'boolean' && typeof userInfo.onEnd == 'boolean') {
|
||||||
|
var onStart = userInfo.onStart;
|
||||||
|
var onEnd = userInfo.onEnd;
|
||||||
|
} else { // In case these options are not yet defined for this userId
|
||||||
|
var onStart = defaultOnStartOption;
|
||||||
|
var onEnd = defaultOnEndOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (emailFound == true) {
|
||||||
|
// We send back the options associated to this userId
|
||||||
|
context.client.json.send({ type: "COLLABROOM",
|
||||||
|
data:{
|
||||||
|
type: "emailNotificationGetUserInfo",
|
||||||
|
payload: {
|
||||||
|
email: email,
|
||||||
|
onStart: onStart,
|
||||||
|
onEnd: onEnd,
|
||||||
|
formName: context.message.data.userInfo.formName,
|
||||||
|
success:true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// No options set for this userId
|
||||||
|
context.client.json.send({ type: "COLLABROOM",
|
||||||
|
data:{
|
||||||
|
type: "emailNotificationGetUserInfo",
|
||||||
|
payload: {
|
||||||
|
formName: context.message.data.userInfo.formName,
|
||||||
|
success:false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to check if an email is valid
|
||||||
|
*/
|
||||||
|
exports.checkEmailValidation = function (email) {
|
||||||
|
var Validator = require('validator').Validator;
|
||||||
|
var validator = new Validator();
|
||||||
|
validator.error = function() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
return validator.check(email).isEmail();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Database manipulation
|
||||||
|
*/
|
||||||
|
|
||||||
// Updates the database with the email record
|
// Updates the database with the email record
|
||||||
exports.setAuthorEmail = function (author, datas, callback){
|
exports.setAuthorEmail = function (author, userInfo, callback){
|
||||||
db.setSub("globalAuthor:" + author, ["email"], datas.email, callback);
|
db.setSub("globalAuthor:" + author, ["email"], userInfo.email, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write email and padId to the database
|
// Write email and padId to the database
|
||||||
exports.setAuthorEmailRegistered = function(datas, authorId, padId){
|
exports.setAuthorEmailRegistered = function(userInfo, authorId, padId){
|
||||||
var timestamp = new Date().getTime();
|
var timestamp = new Date().getTime();
|
||||||
var registered = {
|
var registered = {
|
||||||
authorId: authorId,
|
authorId: authorId,
|
||||||
onStart: datas.email_onStart,
|
onStart: userInfo.email_onStart,
|
||||||
onEnd: datas.email_onEnd,
|
onEnd: userInfo.email_onEnd,
|
||||||
timestamp: timestamp
|
timestamp: timestamp
|
||||||
};
|
};
|
||||||
console.debug("registered", registered, " to ", padId);
|
console.debug("registered", registered, " to ", padId);
|
||||||
// Here we have to basically hack a new value into the database, this isn't clean or polite.
|
// Here we have to basically hack a new value into the database, this isn't clean or polite.
|
||||||
db.get("emailSubscription:" + padId, function(err, value){ // get the current value
|
db.get("emailSubscription:" + padId, function(err, value){ // get the current value
|
||||||
if(!value){value = {};} // if an emailSubscription doesnt exist yet for this padId don't panic
|
if(!value){value = {};} // if an emailSubscription doesnt exist yet for this padId don't panic
|
||||||
value[datas.email] = registered; // add the registered values to the object
|
value[userInfo.email] = registered; // add the registered values to the object
|
||||||
console.warn("written to database");
|
console.warn("written to database");
|
||||||
db.set("emailSubscription:" + padId, value); // stick it in the database
|
db.set("emailSubscription:" + padId, value); // stick it in the database
|
||||||
});
|
});
|
||||||
|
@ -197,25 +323,27 @@ exports.setAuthorEmailRegistered = function(datas, authorId, padId){
|
||||||
}
|
}
|
||||||
|
|
||||||
// Updates the database by removing the email record for that AuthorId
|
// Updates the database by removing the email record for that AuthorId
|
||||||
exports.unsetAuthorEmail = function (author, datas, callback){
|
exports.unsetAuthorEmail = function (author, userInfo){
|
||||||
db.get("globalAuthor:" + author, function(err, value){ // get the current value
|
db.get("globalAuthor:" + author, function(err, value){ // get the current value
|
||||||
|
|
||||||
// Remove the email option from the datas
|
if (value['email'] == userInfo.email) {
|
||||||
delete value['email'];
|
// Remove the email option from the datas
|
||||||
|
delete value['email'];
|
||||||
|
|
||||||
// Write the modified datas back in the Db
|
// Write the modified datas back in the Db
|
||||||
db.set("globalAuthor:" + author, value);
|
db.set("globalAuthor:" + author, value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove email, options and padId from the database
|
// Remove email, options and padId from the database
|
||||||
exports.unsetAuthorEmailRegistered = function(datas, authorId, padId){
|
exports.unsetAuthorEmailRegistered = function(userInfo, authorId, padId){
|
||||||
console.debug("unregistered", datas.email, " to ", padId);
|
console.debug("unregistered", userInfo.email, " to ", padId);
|
||||||
|
|
||||||
db.get("emailSubscription:" + padId, function(err, value){ // get the current value
|
db.get("emailSubscription:" + padId, function(err, value){ // get the current value
|
||||||
|
|
||||||
// remove the registered options from the object
|
// remove the registered options from the object
|
||||||
delete value[datas.email];
|
delete value[userInfo.email];
|
||||||
|
|
||||||
// Write the modified datas back in the Db
|
// Write the modified datas back in the Db
|
||||||
console.warn("written to database");
|
console.warn("written to database");
|
||||||
|
|
|
@ -15,5 +15,12 @@
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.4.1"
|
"node": ">= 0.4.1"
|
||||||
}
|
},
|
||||||
|
"readme": "# Description\nThis plugin allows users to subscribe to pads and receive email updates when a pad is being modified. You can modify the frequency. This plugin is very much in alpha stage and has a lot of things TODO (See TODO).\n\n# Installation\nMake sure an SMTP gateway is installed IE postfix\nConfigure SPF and RDNS records to ensure proper mail flow <-- Search online\nCopy/Edit the below to your settings.json\nConnect to a pad, Click on the Share/Embed link and enter in your email address.\nOpen that pad in ANOTHER BROWSER then begin modifying, you should receive an email when the pad has begun editing and once the pad has gone stale (when everyone stops editing it and a time period passes).\nNOTE: You will NOT receive an email if you(the author that registered their email) are currently on or editing that pad!\n\n```\n \"ep_email_notifications\" : {\n checkFrequency: 6000, // checkFrequency = How frequently(milliseconds) to check for pad updates -- Move me to the settings file\n staleTime: 30000, // staleTime = How stale(milliseconds) does a pad need to be before notifying subscribers? Move me to settings\n fromName: \"Etherpad SETTINGS FILE!\",\n fromEmail: \"pad@etherpad.org\",\n urlToPads: \"http://beta.etherpad.org/p/\", // urlToPads = The URL to your pads note the trailing /\n emailServer: { // See https://github.com/eleith/emailjs for settings\n host: \"127.0.0.1\"\n }\n }\n```\n\n# TODO\n* Clean up all code\n\n# FUTURE VERSIONS TODO\n* v2 - Get the modified contents from the API HTML diff and append that to the Email and make the email from the server HTML not plain text\n* v2 - a point to unsubscribe and validate/verify email https://github.com/alfredwesterveld/node-email-verification\n* v2 - Keep a record of when a user was last on a pad\n",
|
||||||
|
"readmeFilename": "README.md",
|
||||||
|
"_id": "ep_email_notifications@0.0.6",
|
||||||
|
"dist": {
|
||||||
|
"shasum": "1f32eee4c8d5f3903c549b5a7985afc0053ed451"
|
||||||
|
},
|
||||||
|
"_from": "ep_email_notifications"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,34 @@
|
||||||
.ep_email_settings {
|
.ep_email_settings {
|
||||||
display: none;
|
display: none;
|
||||||
padding-left: 1.5em;
|
padding: 0.2em 0.2em 0.2em 0.5em;
|
||||||
padding: .2em;
|
}
|
||||||
|
|
||||||
|
.ep_email_buttons {
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ep_email_checkbox {
|
||||||
|
margin-left:0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ep_email_input {
|
.ep_email_input {
|
||||||
padding:.2em;
|
padding:.2em;
|
||||||
width:177px;
|
width:177px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ep_email_form_popup > p {
|
||||||
|
font-size:x-small;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ep_email_form_popup .ep_email_buttons {
|
||||||
|
margin-top: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ep_email_form_popup .ep_email_checkbox {
|
||||||
|
margin-top: .2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ep_email_form_popup .ep_email_input {
|
||||||
|
margin: .3em 0;
|
||||||
|
width:95%;
|
||||||
|
}
|
||||||
|
|
|
@ -1,89 +1,181 @@
|
||||||
var cookie = require('ep_etherpad-lite/static/js/pad_cookie').padcookie;
|
var cookie = require('ep_etherpad-lite/static/js/pad_cookie').padcookie;
|
||||||
var firstRun = true;
|
var optionsAlreadyRecovered = false;
|
||||||
|
|
||||||
if(typeof exports == 'undefined'){
|
if(typeof exports == 'undefined'){
|
||||||
var exports = this['mymodule'] = {};
|
var exports = this['mymodule'] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.postAceInit = function(hook, context){
|
exports.postAceInit = function(hook, context){
|
||||||
// Uncheck the checkbox
|
// If plugin settings set panel form in mysettings menu
|
||||||
$('#options-emailNotifications').attr('checked', false);
|
if (clientVars.panelDisplayLocation.mysettings == true) {
|
||||||
setDefaultOptions();
|
// Uncheck the checkbox incase of reminiscence
|
||||||
|
$('#options-emailNotifications').prop('checked', false);
|
||||||
|
|
||||||
/* on click */
|
$('#options-emailNotifications').on('click', function() {
|
||||||
$('#options-emailNotifications').on('click', function() {
|
if (!optionsAlreadyRecovered) {
|
||||||
if (firstRun) {
|
getDataForUserId('ep_email_form_mysettings');
|
||||||
getDatasForUserId();
|
optionsAlreadyRecovered = true;
|
||||||
firstRun = false;
|
} else {
|
||||||
} else {
|
$('.ep_email_settings').slideToggle();
|
||||||
$('.ep_email_settings').slideToggle();
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Prepare subscription before submit form
|
// Prepare subscription before submit form
|
||||||
$('#ep_email_subscribe').on('click', function() {
|
$('[name=ep_email_subscribe]').on('click', function(e) {
|
||||||
$('#ep_email_option').val('subscribe');
|
$('[name=ep_email_option]').val('subscribe');
|
||||||
checkAndSend();
|
checkAndSend(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Prepare unsubscription before submit form
|
// Prepare unsubscription before submit form
|
||||||
$('#ep_email_unsubscribe').on('click', function() {
|
$('[name=ep_email_unsubscribe]').on('click', function(e) {
|
||||||
$('#ep_email_option').val('unsubscribe');
|
$('[name=ep_email_option]').val('unsubscribe');
|
||||||
checkAndSend();
|
checkAndSend(e);
|
||||||
});
|
});
|
||||||
|
|
||||||
// subscribe by email can be active..
|
// subscribe by email can be active..
|
||||||
$('.ep_email_form').submit(function(){
|
$('#ep_email_form_mysettings').submit(function(){
|
||||||
sendEmailToServer();
|
sendEmailToServer('ep_email_form_mysettings');
|
||||||
$('.ep_email_settings').slideToggle();
|
return false;
|
||||||
$('#options-emailNotifications').attr('checked', false);
|
});
|
||||||
return false;
|
} else {
|
||||||
});
|
// Hide the notification menu in mysettings
|
||||||
|
$('#options-emailNotifications').parent().hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If settings set popup panel form to true, show it
|
||||||
|
if (clientVars.panelDisplayLocation.popup == true) {
|
||||||
|
// after 10 seconds if we dont already have an email for this author then prompt them
|
||||||
|
setTimeout(function(){initPopupForm()},10000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.handleClientMessage_emailSubscriptionSuccess = function(hook, context){ // was subscribing to the email a big win or fail?
|
exports.handleClientMessage_emailSubscriptionSuccess = function(hook, context){ // was subscribing to the email a big win or fail?
|
||||||
if(context.payload == false){
|
if(context.payload.success == false) {
|
||||||
showAlreadyRegistered();
|
showAlreadyRegistered(context.payload.type);
|
||||||
}else{
|
$('#' + context.payload.formName + ' [name=ep_email]').select();
|
||||||
|
} else {
|
||||||
showRegistrationSuccess();
|
showRegistrationSuccess();
|
||||||
|
|
||||||
|
if (clientVars.panelDisplayLocation.mysettings == true && $('.ep_email_settings').is(":visible")) {
|
||||||
|
$('.ep_email_settings').slideToggle();
|
||||||
|
$('#options-emailNotifications').prop('checked', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientVars.panelDisplayLocation.popup == true && $('#ep_email_form_popup').is(":visible")) {
|
||||||
|
$('#ep_email_form_popup').parent().parent().parent().hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.handleClientMessage_emailUnsubscriptionSuccess = function(hook, context){ // was subscribing to the email a big win or fail?
|
exports.handleClientMessage_emailUnsubscriptionSuccess = function(hook, context){ // was subscribing to the email a big win or fail?
|
||||||
if(context.payload == false){
|
if(context.payload.success == false) {
|
||||||
showWasNotRegistered();
|
showWasNotRegistered();
|
||||||
}else{
|
$('#' + context.payload.formName + ' [name=ep_email]').select();
|
||||||
|
} else {
|
||||||
showUnregistrationSuccess();
|
showUnregistrationSuccess();
|
||||||
|
|
||||||
|
if (clientVars.panelDisplayLocation.mysettings == true && $('.ep_email_settings').is(":visible")) {
|
||||||
|
$('.ep_email_settings').slideToggle();
|
||||||
|
$('#options-emailNotifications').prop('checked', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clientVars.panelDisplayLocation.popup == true && $('#ep_email_form_popup').is(":visible")) {
|
||||||
|
$('#ep_email_form_popup').parent().parent().parent().hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.handleClientMessage_emailNotificationGetUserInfo = function (hook, context) { // return the existing options for this userId
|
exports.handleClientMessage_emailNotificationGetUserInfo = function (hook, context) { // return the existing options for this userId
|
||||||
var datas = context.payload;
|
var result = context.payload;
|
||||||
if(datas.success == true){ // If datas were found, set the options with them
|
if(result.success == true){ // If data found, set the options with them
|
||||||
if (datas.email) $('#ep_email').val(datas.email);
|
$('[name=ep_email]').val(result.email);
|
||||||
if (datas.onStart && typeof datas.onStart === 'boolean') $('#ep_email_onStart').attr('checked', datas.onStart);
|
$('[name=ep_email_onStart]').prop('checked', result.onStart);
|
||||||
if (datas.onEnd && typeof datas.onEnd === 'boolean') $('#ep_email_onEnd').attr('checked', datas.onEnd);
|
$('[name=ep_email_onEnd]').prop('checked', result.onEnd);
|
||||||
} else { // No datas were found, set the options to default values
|
} else { // No data found, set the options to default values
|
||||||
setDefaultOptions();
|
$('[name=ep_email_onStart]').prop('checked', true);
|
||||||
|
$('[name=ep_email_onEnd]').prop('checked', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.ep_email_settings').slideToggle();
|
if (result.formName == 'ep_email_form_mysettings') {
|
||||||
|
$('.ep_email_settings').slideToggle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the options in the frame to a default value
|
* Initialize the popup panel form for subscription
|
||||||
*/
|
*/
|
||||||
function setDefaultOptions() {
|
function initPopupForm(){
|
||||||
$('#ep_email_onStart').attr('checked', true);
|
var popUpIsAlreadyVisible = $('#ep_email_form_popup').is(":visible");
|
||||||
$('#ep_email_onEnd').attr('checked', false);
|
if(!popUpIsAlreadyVisible){ // if the popup isn't already visible
|
||||||
|
var cookieVal = pad.getPadId() + "email";
|
||||||
|
if(cookie.getPref(cookieVal) !== "true"){ // if this user hasn't already subscribed
|
||||||
|
askClientToEnterEmail(); // ask the client to register TODO uncomment me for a pop up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clientHasAlreadyRegistered(){ // Has the client already registered for emails on this?
|
||||||
|
// Given a specific AuthorID do we have an email address in the database?
|
||||||
|
// Given that email address is it registered to this pad?
|
||||||
|
// need to pass the server a message to check
|
||||||
|
var userId = pad.getUserId();
|
||||||
|
var message = {};
|
||||||
|
message.type = 'USERINFO_AUTHOR_EMAIL_IS_REGISTERED_TO_PAD';
|
||||||
|
message.userInfo = {};
|
||||||
|
message.userInfo.userId = userId;
|
||||||
|
pad.collabClient.sendMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function askClientToEnterEmail(){
|
||||||
|
var formContent = $('.ep_email_settings')
|
||||||
|
.html()
|
||||||
|
.replace('ep_email_form_mysettings', 'ep_email_form_popup');
|
||||||
|
|
||||||
|
$.gritter.add({
|
||||||
|
// (string | mandatory) the heading of the notification
|
||||||
|
title: "Email subscription",
|
||||||
|
// (string | mandatory) the text inside the notification
|
||||||
|
text: "<p>(Receive an email when someone modifies this pad)</p>" + formContent,
|
||||||
|
// (bool | optional) if you want it to fade out on its own or just sit there
|
||||||
|
sticky: true,
|
||||||
|
// (int | optional) the time you want it to be alive for before fading out
|
||||||
|
time: 2000,
|
||||||
|
// the function to bind to the form
|
||||||
|
after_open: function(e){
|
||||||
|
$('#ep_email_form_popup').submit(function(){
|
||||||
|
sendEmailToServer('ep_email_form_popup');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prepare subscription before submit form
|
||||||
|
$('#ep_email_form_popup [name=ep_email_subscribe]').on('click', function(e) {
|
||||||
|
$('#ep_email_form_popup [name=ep_email_option]').val('subscribe');
|
||||||
|
checkAndSend(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prepare unsubscription before submit form
|
||||||
|
$('#ep_email_form_popup [name=ep_email_unsubscribe]').on('click', function(e) {
|
||||||
|
$('#ep_email_form_popup [name=ep_email_option]').val('unsubscribe');
|
||||||
|
checkAndSend(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
getDataForUserId('ep_email_form_popup');
|
||||||
|
optionsAlreadyRecovered = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control options before submitting the form
|
* Control options before submitting the form
|
||||||
*/
|
*/
|
||||||
function checkAndSend() {
|
function checkAndSend(e) {
|
||||||
var email = getEmail();
|
var formName = $(e.currentTarget.parentNode).attr('id');
|
||||||
if (email && $('#ep_email_option').val() == 'subscribe' && !$('#ep_email_onStart').is(':checked') && !$('#ep_email_onEnd').is(':checked')) {
|
|
||||||
|
var email = $('#' + formName + ' [name=ep_email]').val();
|
||||||
|
|
||||||
|
if (email && $('#' + formName + ' [name=ep_email_option]').val() == 'subscribe'
|
||||||
|
&& !$('#' + formName + ' [name=ep_email_onStart]').is(':checked')
|
||||||
|
&& !$('#' + formName + ' [name=ep_email_onEnd]').is(':checked')) {
|
||||||
$.gritter.add({
|
$.gritter.add({
|
||||||
// (string | mandatory) the heading of the notification
|
// (string | mandatory) the heading of the notification
|
||||||
title: "Email subscription error",
|
title: "Email subscription error",
|
||||||
|
@ -91,36 +183,26 @@ function checkAndSend() {
|
||||||
text: "You need to check at least one of the two options from 'Send a mail when someone..'"
|
text: "You need to check at least one of the two options from 'Send a mail when someone..'"
|
||||||
});
|
});
|
||||||
} else if (email) {
|
} else if (email) {
|
||||||
$('.ep_email_form').submit();
|
$('#' + formName).submit();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the email from the user
|
|
||||||
*/
|
|
||||||
function getEmail() {
|
|
||||||
var email = $('#ep_email').val();
|
|
||||||
if(!email){ // if we're not using the top value use the notification value
|
|
||||||
email = $('#ep_email_notification').val();
|
|
||||||
}
|
|
||||||
return email;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ask the server to register the email
|
* Ask the server to register the email
|
||||||
*/
|
*/
|
||||||
function sendEmailToServer(){
|
function sendEmailToServer(formName){
|
||||||
var email = getEmail();
|
var email = $('#' + formName + ' [name=ep_email]').val();
|
||||||
var userId = pad.getUserId();
|
var userId = pad.getUserId();
|
||||||
var message = {};
|
var message = {};
|
||||||
message.type = 'USERINFO_UPDATE';
|
message.type = 'USERINFO_UPDATE';
|
||||||
message.userInfo = {};
|
message.userInfo = {};
|
||||||
message.padId = pad.getPadId();
|
message.padId = pad.getPadId();
|
||||||
message.userInfo.email = email;
|
message.userInfo.email = email;
|
||||||
message.userInfo.email_option = $('#ep_email_option').val();
|
message.userInfo.email_option = $('#' + formName + ' [name=ep_email_option]').val();
|
||||||
message.userInfo.email_onStart = $('#ep_email_onStart').is(':checked');
|
message.userInfo.email_onStart = $('#' + formName + ' [name=ep_email_onStart]').is(':checked');
|
||||||
message.userInfo.email_onEnd = $('#ep_email_onEnd').is(':checked');
|
message.userInfo.email_onEnd = $('#' + formName + ' [name=ep_email_onEnd]').is(':checked');
|
||||||
|
message.userInfo.formName = formName;
|
||||||
message.userInfo.userId = userId;
|
message.userInfo.userId = userId;
|
||||||
if(email){
|
if(email){
|
||||||
pad.collabClient.sendMessage(message);
|
pad.collabClient.sendMessage(message);
|
||||||
|
@ -132,13 +214,14 @@ function sendEmailToServer(){
|
||||||
* Thanks to the userId, we can get back from the Db the options set for this user
|
* Thanks to the userId, we can get back from the Db the options set for this user
|
||||||
* and fill the fields with them
|
* and fill the fields with them
|
||||||
*/
|
*/
|
||||||
function getDatasForUserId() {
|
function getDataForUserId(formName) {
|
||||||
var userId = pad.getUserId();
|
var userId = pad.getUserId();
|
||||||
var message = {};
|
var message = {};
|
||||||
message.type = 'USERINFO_GET';
|
message.type = 'USERINFO_GET';
|
||||||
message.padId = pad.getPadId();
|
message.padId = pad.getPadId();
|
||||||
message.userInfo = {};
|
message.userInfo = {};
|
||||||
message.userInfo.userId = userId;
|
message.userInfo.userId = userId;
|
||||||
|
message.userInfo.formName = formName;
|
||||||
|
|
||||||
pad.collabClient.sendMessage(message);
|
pad.collabClient.sendMessage(message);
|
||||||
}
|
}
|
||||||
|
@ -162,12 +245,19 @@ function showRegistrationSuccess(){
|
||||||
/**
|
/**
|
||||||
* The client already registered for emails on this pad so notify the UI
|
* The client already registered for emails on this pad so notify the UI
|
||||||
*/
|
*/
|
||||||
function showAlreadyRegistered(){
|
function showAlreadyRegistered(type){
|
||||||
|
if (type == "malformedEmail") {
|
||||||
|
var msg = "The email address is malformed";
|
||||||
|
} else if (type == "alreadyRegistered") {
|
||||||
|
var msg = "You are already registered for emails for this pad";
|
||||||
|
} else {
|
||||||
|
var msg = "Unknown error";
|
||||||
|
}
|
||||||
$.gritter.add({
|
$.gritter.add({
|
||||||
// (string | mandatory) the heading of the notification
|
// (string | mandatory) the heading of the notification
|
||||||
title: "Email subscription",
|
title: "Email subscription",
|
||||||
// (string | mandatory) the text inside the notification
|
// (string | mandatory) the text inside the notification
|
||||||
text: "You are already registered for emails for this pad",
|
text: msg,
|
||||||
// (bool | optional) if you want it to fade out on its own or just sit there
|
// (bool | optional) if you want it to fade out on its own or just sit there
|
||||||
sticky: false
|
sticky: false
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,20 +1,21 @@
|
||||||
<p>
|
<p>
|
||||||
<input type="checkbox" id="options-emailNotifications"></input>
|
<input type="checkbox" id="options-emailNotifications"></input>
|
||||||
<label for="options-emailNotifications">Email Notifications</label>
|
<label for="options-emailNotifications">Email Notifications</label>
|
||||||
<div class="ep_email_settings">
|
<div class="ep_email_settings">
|
||||||
<form class='ep_email_form'>
|
<form id='ep_email_form_mysettings'>
|
||||||
<input id='ep_email' class='ep_email_input' placeholder='your@email.com' type=email>
|
<input name='ep_email' class='ep_email_input' placeholder='your@email.com' type=email>
|
||||||
<label>Send a mail when someone..</label>
|
<br />
|
||||||
<br />
|
<label>Send a mail when someone..</label>
|
||||||
<input type="checkbox" style="margin-left:0.3em;" id="ep_email_onStart"></input>
|
<br />
|
||||||
<label for="ep_email_onStart">starts editing the pad</label>
|
<input name='ep_email_onStart' type="checkbox" class="ep_email_checkbox"></input>
|
||||||
<br />
|
<label for="ep_email_onStart">starts editing the pad</label>
|
||||||
<input type="checkbox" style="margin-left:0.3em;" id="ep_email_onEnd"></input>
|
<br />
|
||||||
<label for="ep_email_onEnd">finish editing the pad</label>
|
<input name='ep_email_onEnd' type="checkbox" class="ep_email_checkbox"></input>
|
||||||
<input id='ep_email_option'type=hidden >
|
<label for="ep_email_onEnd">finish editing the pad</label>
|
||||||
</form>
|
<input name='ep_email_option' type=hidden >
|
||||||
<br />
|
<br />
|
||||||
<input style="padding:5px;" id='ep_email_subscribe' type=button value=subscribe>
|
<input name='ep_email_subscribe' type=button class="ep_email_buttons" value=subscribe>
|
||||||
<input style="padding:5px;" id='ep_email_unsubscribe'type=button value=unsubscribe>
|
<input name='ep_email_unsubscribe'type=button class="ep_email_buttons" value=unsubscribe>
|
||||||
</div>
|
</form>
|
||||||
|
</div>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
<br>
|
|
||||||
<h2>Recieve email notifications on change</h2>
|
|
||||||
<form class='ep_email_form'><label for='ep_email'><input id='ep_email' placeholder='your@email.com' style="padding:5px;margin-top:10px;width:300px;" type=email><input style="padding:5px;" type=submit value=subscribe></form>
|
|
Loading…
Reference in a new issue