New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

nodebb-plugin-shoutbox

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nodebb-plugin-shoutbox - npm Package Compare versions

Comparing version 0.1.0 to 0.2.0

lib/commands.js

167

lib/backend.js

@@ -9,7 +9,8 @@ var async = require('async'),

Backend = {
addShout: function(fromuid, content, callback) {
(function(Backend) {
Backend.addShout = function(fromuid, content, callback) {
db.incrObjectField('global', 'nextSid', function(err, sid) {
if (err) {
return callback(err, null);
return callback(err);
}

@@ -24,11 +25,17 @@

db.setObject('shout:' + sid, shout);
db.listAppend('shouts', sid);
db.setObject('shout:' + sid, shout, function(err) {
if (err) {
return callback(err);
}
Backend.updateShoutTime(fromuid);
shout.sid = sid;
callback(null, shout);
db.listAppend('shouts', sid);
getShouts([sid], true, function(err, shouts) {
callback(err, shouts ? shouts[0] : null);
});
});
});
},
getShout: function(sid, callback) {
};
Backend.getRawShout = function(sid, callback) {
db.getObject('shout:' + sid, function(err, shout) {

@@ -40,7 +47,8 @@ if (err) {

});
},
getShouts: function(start, end, callback) {
};
Backend.getShouts = function(start, end, callback) {
db.getListRange('shouts', start, end, function(err, sids) {
if (err) {
return callback(err, null);
return callback(err);
}

@@ -52,35 +60,60 @@

function getShout(sid, next) {
db.getObject('shout:' + sid, function(err, message) {
if (err) {
return next(err);
}
if (message.deleted === '1') {
getShouts(sids, false, callback);
});
};
function getShouts(sids, isNew, callback) {
var keys = sids.map(function(sid) {
return 'shout:' + sid;
});
db.getObjects(keys, function(err, shouts) {
if (err) {
return callback(err);
}
var userData, uids = shouts.map(function(s) {
return parseInt(s.deleted, 10) !== 1 ? parseInt(s.fromuid, 10) : null;
}).filter(function(u, index, self) {
return u === null ? false : self.indexOf(u) === index;
});
User.getMultipleUserFields(uids, ['username', 'userslug', 'picture', 'status'], function(err, usersData) {
if (err) {
return callback(err);
}
shouts = shouts.map(function (shout, index) {
shout.sid = sids[index];
return shout;
});
async.map(shouts, function(shout, next) {
if (parseInt(shout.deleted, 10) === 1) {
return next(null);
}
User.getMultipleUserFields([message.fromuid], ['username', 'userslug', 'picture', 'status'], function(err, userData) {
userData = userData[0];
userData.uid = message.fromuid;
Backend.parse(message.content, userData, false, function(err, data) {
message.user = data.userData;
message.user.isAdmin = data.isAdmin;
message.isNew = data.isNew;
message.content = data.content;
message.sid = sid;
next(null, message);
});
userData = usersData[uids.indexOf(parseInt(shout.fromuid))];
userData.uid = shout.fromuid;
Backend.parse(shout.content, userData, isNew, function(err, s) {
shout.user = s.user;
shout.isNew = s.isNew;
shout.content = s.content;
next(null, shout);
});
});
}
}, callback);
});
});
}
async.map(sids, getShout, callback);
});
},
parse: function(message, userData, isNew, callback) {
Backend.parse = function(message, userData, isNew, callback) {
Plugins.fireHook('filter:post.parse', message, function(err, parsed) {
User.isAdministrator(userData.uid, function(err, isAdmin) {
userData.status = NodeBB.SocketIndex.isUserOnline(userData.uid) ? (userData.status || 'online') : 'offline';
userData.isAdmin = isAdmin;
var shout = {
userData: userData,
isAdmin: isAdmin,
user: userData,
isNew: isNew,

@@ -93,4 +126,5 @@ content: parsed

});
},
removeShout: function(sid, uid, callback) {
};
Backend.removeShout = function(sid, uid, callback) {
User.isAdministrator(uid, function(err, isAdmin) {

@@ -101,2 +135,3 @@ db.getObjectField('shout:' + sid, 'fromuid', function(err, fromuid) {

}
if (fromuid === uid || isAdmin) {

@@ -114,4 +149,5 @@ db.setObjectField('shout:' + sid, 'deleted', '1', function (err, result) {

});
},
editShout: function(sid, msg, uid, callback) {
};
Backend.editShout = function(sid, msg, uid, callback) {
User.isAdministrator(uid, function(err, isAdmin) {

@@ -122,2 +158,3 @@ db.getObjectField('shout:' + sid, 'fromuid', function(err, fromuid) {

}
if (fromuid === uid || isAdmin) {

@@ -128,14 +165,5 @@ db.setObjectField('shout:' + sid, 'content', msg, function (err, result) {

}
User.getMultipleUserFields([fromuid], ['username', 'userslug', 'picture', 'status'], function(err, userData) {
userData = userData[0];
userData.uid = fromuid;
Backend.parse(msg, userData, false, function(err, data) {
var shout = {};
shout.user = data.userData;
shout.user.isAdmin = data.isAdmin;
shout.isNew = data.isNew;
shout.content = data.content;
shout.sid = sid;
return callback(null, shout);
});
getShouts([sid], false, function(err, shouts) {
callback(err, shouts ? shouts[0] : null);
});

@@ -148,6 +176,7 @@ });

});
},
pruneDeleted: function(uid, callback) {
};
Backend.pruneDeleted = function(uid, callback) {
User.isAdministrator(uid, function(err, isAdmin) {
if (isAdmin === true) {
if (isAdmin) {
db.getListRange('shouts', 0, -1, function(err, sids) {

@@ -160,12 +189,11 @@ if (err || !sids || !sids.length) {

db.getObjectField('shout:' + sid, 'deleted', function(err, isDeleted) {
if (isDeleted === '1') {
if (parseInt(isDeleted, 10) === 1) {
db.delete('shout:' + sid);
db.listRemoveAll('shouts', sid);
next()
}
next(null);
next();
});
}
async.map(sids, deleteShout, function(err) {
async.eachSeries(sids, deleteShout, function(err) {
if (err) {

@@ -181,4 +209,5 @@ return callback(err, false);

});
},
removeAll: function(uid, callback) {
};
Backend.removeAll = function(uid, callback) {
User.isAdministrator(uid, function(err, isAdmin) {

@@ -210,12 +239,4 @@ if (isAdmin === true) {

});
},
updateShoutTime: function(uid, callback) {
db.sortedSetAdd('uid:' + uid + ':shouts', Date.now(), 0, function(err) {
if (callback) {
callback(err);
}
});
}
}
};
module.exports = Backend;
})(module.exports);
var NodeBB = module.require('./nodebb'),
pjson = require('../package.json'),
Meta = NodeBB.Meta,
Settings = NodeBB.Settings,
db = NodeBB.db;
var Config = {
plugin: {
(function(Config) {
Config.plugin = {
name: 'Shoutbox',
id: 'shoutbox',
description: 'Shoutbox widget.',
version: pjson.version,
description: pjson.description,
icon: 'fa-bullhorn',
route: '/shoutbox'
},
prefix: 'shoutbox:',
keys: ['headerlink', 'shoutlimit', 'features'],
defaults: {
headerlink: '0',
shoutlimit: 25,
features: '{}'
},
features: [{
name: 'Gists',
id: 'gist',
description: 'Easily create Gists',
icon: 'fa-github-alt',
button: 'Create Gist',
enabled: true
}, {
name: 'Archive',
id: 'archive',
description: 'View older posts',
icon: 'fa-archive',
button: 'View Archive',
enabled: true
}, {
name: 'Bugs',
id: 'bug',
description: 'Report bugs quickly',
icon: 'fa-bug',
button: 'Report Bug',
enabled: true
}],
get: function(keys) {
var get = function(key) {
return Meta.config[Config.prefix + key] || Config.defaults[key];
};
var features = [
{
name: 'Gists',
id: 'gist',
description: 'Easily create Gists',
icon: 'fa-github-alt',
button: 'Create Gist',
enabled: true
},
{
name: 'Archive',
id: 'archive',
description: 'View older posts',
icon: 'fa-archive',
button: 'View Archive',
enabled: true
},
{
name: 'Bugs',
id: 'bug',
description: 'Report bugs quickly',
icon: 'fa-bug',
button: 'Report Bug',
enabled: true
}
];
if (Array.isArray(keys)) {
var result = {};
for(var i = 0, l = keys.length; i < l; i++) {
if (Config.keys.indexOf(keys[i]) !== -1) {
result[keys[i]] = get(keys[i]);
}
}
return result;
} else {
return get(keys);
var adminDefaults = {
toggles: {
headerLink: false,
features: (function() {
var defaults = {};
features.forEach(function(el) {
defaults[el.id] = el.enabled;
});
return defaults;
})()
},
limits: {
shoutLimit: "25"
}
},
api: function(callback) {
var config = Config.get(['features']),
featureData = JSON.parse(config.features);
config.features = Config.features.slice(0);
if (featureData && Object.keys(featureData).length > 0) {
config.features.map(function(item) {
return featureData[item.id] ? item.enabled = featureData[item.id].enabled : item.enabled;
});
};
var userDefaults = {
// toggles: {
// sound: true,
// notification: true,
// hide: false
// },
// muted: '',
'shoutbox:toggles:sound': true,
'shoutbox:toggles:notification': true,
'shoutbox:toggles:hide': false,
'shoutbox:muted': ''
};
Config.global = new Settings(Config.plugin.id, Config.plugin.version, adminDefaults);
Config.adminSockets = {
sync: function() {
Config.global.sync();
},
getDefaults: function(socket, data, callback) {
callback(null, Config.global.createDefaultWrapper());
}
callback(config);
}
};
};
Config.settings = {
keys: ['sound', 'notification', 'hide'],
defaults: {
sound: 1,
notification: 1,
hide: 0
},
get: function(data, callback) {
db.getObjectFields('user:' + data.uid + ':settings', Config.settings.keys.map(function(e) {
return Config.prefix + e;
}), function(err, result) {
//Config.user = new Settings(Config.plugin.id + 'User', Config.plugin.version, userDefaults);
Config.user = {};
Config.user.get = function(data, callback) {
db.getObjectFields('user:' + data.uid + ':settings', Object.keys(userDefaults), function(err, result) {
for (var k in result) {
if (result.hasOwnProperty(k) && k != '_key') {
data.settings[k] = result[k] !== null ? result[k] : Config.settings.defaults[k.split(':')[1]];
data.settings[k] = result[k] !== null ? result[k] : userDefaults[k];
}
}
callback(null, data);
});
},
save: function(data, callback) {
};
Config.user.save = function(data, callback) {
if (data.uid) {
var s;
for (var k in Config.settings.keys) {
if (Config.settings.keys.hasOwnProperty(k)) {
s = Config.prefix + Config.settings.keys[k];
if (data.settings[s] !== undefined) {
db.setObjectField('user:' + data.uid + ':settings', s, data.settings[s]);
}
var keys = Object.keys(userDefaults), cur;
for (var i = 0, l = keys.length; i < l; i++) {
cur = keys[i];
if (data.settings[cur] !== undefined) {
db.setObjectField('user:' + data.uid + ':settings', cur, data.settings[cur]);
}

@@ -107,5 +112,43 @@ }

}
}
}
};
module.exports = Config;
Config.userSockets = {
getSettings: function(socket, data, callback) {
if (socket.uid === 0) {
return;
}
Config.user.get({ uid: socket.uid, settings: {} }, function(err, result) {
var settings = result.settings;
settings['shoutbox:shoutLimit'] = parseInt(Config.global.get('limits.shoutLimit'), 10);
callback(null, {
settings: settings
});
});
},
saveSettings: function(socket, data, callback) {
if (!data || !data.key || !socket.uid) {
return callback(null, false);
}
var setting = {};
setting[data.key] = data.value;
Config.user.save({ uid: socket.uid, settings: setting}, callback);
}
};
Config.getTemplateData = function(callback) {
var featureConfig = Config.global.get('toggles.features'),
data = {};
data.features = features.slice(0).map(function(item) {
item.enabled = featureConfig[item.id];
return item;
});
callback(data);
};
})(module.exports);

@@ -1,8 +0,12 @@

module.exports = {
Meta: module.parent.parent.require('./meta'),
User: module.parent.parent.require('./user'),
Plugins: module.parent.parent.require('./plugins'),
SocketIndex: module.parent.parent.require('./socket.io/index'),
ModulesSockets: module.parent.parent.require('./socket.io/modules'),
db: module.parent.parent.require('./database')
}
(function(NodeBB) {
module.exports = {
Settings: NodeBB.require('./settings'),
Meta: NodeBB.require('./meta'),
User: NodeBB.require('./user'),
Plugins: NodeBB.require('./plugins'),
SocketIndex: NodeBB.require('./socket.io/index'),
SocketPlugins: NodeBB.require('./socket.io/plugins'),
SocketAdmin: NodeBB.require('./socket.io/admin').plugins,
db: NodeBB.require('./database')
}
})(module.parent.parent);

@@ -6,133 +6,146 @@ var S = require('string'),

Backend = require('./backend'),
Commands = require('./commands'),
User = NodeBB.User,
SocketIndex = NodeBB.SocketIndex;
//todo clean this up and improve
var Sockets = {
get: function(socket, data, callback) {
var start, end;
if (data && (data.start && data.end)) {
start = parseInt(data.start, 10);
end = parseInt(data.end, 10);
} else {
start = -(parseInt(Config.get('shoutlimit'), 10) - 1);
end = -1;
}
if (socket.uid) {
Backend.getShouts(start, end, function(err, messages) {
if (err)
return callback(null, []);
(function(Sockets) {
callback(null, messages);
});
} else {
callback(null, []);
}
},
send: function(socket, data, callback) {
if(!data || socket.uid === 0) {
return callback(new Error('invalid-data'));
}
var uidSocketIndex = {},
handlers = {
get: function(socket, data, callback) {
var start, end;
var msg = S(data.message).stripTags().trim().s;
if (msg.length) {
User.getMultipleUserFields([socket.uid], ['username', 'userslug', 'picture', 'status'], function(err, userData) {
if(err) {
return;
}
if (data && data.start) {
start = parseInt(data.start, 10);
end = start + parseInt(Config.global.get('limits.shoutLimit'), 10);
} else {
start = -(parseInt(Config.global.get('limits.shoutLimit'), 10));
end = -1;
}
userData = userData[0];
userData.uid = socket.uid;
Backend.parse(msg, userData, true, function(err, data) {
Backend.addShout(socket.uid, msg, function(err, message) {
message.user = data.userData;
message.user.isAdmin = data.isAdmin;
message.isNew = data.isNew;
message.content = data.content;
SocketIndex.server.sockets.emit('event:shoutbox.receive', message);
});
if (socket.uid) {
updateUidSocketIndex(socket);
Backend.getShouts(start, end, function(err, messages) {
if (err) {
return callback(null, []);
}
callback(null, messages);
});
});
}
},
remove: function(socket, data, callback) {
if (data && data.sid) {
Backend.removeShout(data.sid.toString(), socket.uid, function(err, result) {
if (result === true) {
SocketIndex.server.sockets.emit('event:shoutbox.delete', {
sid: data.sid
});
}
callback(err, result);
});
}
},
edit: function(socket, data, callback) {
if (data && data.sid) {
var msg = S(data.edited).stripTags().s;
Backend.editShout(data.sid.toString(), msg, socket.uid, function(err, result) {
if (err === null) {
} else {
callback(null, []);
}
},
send: function(socket, data, callback) {
if (!data || socket.uid === 0) {
return callback(new Error('invalid-data'));
}
updateUidSocketIndex(socket);
var msg = S(data.message).stripTags().trim().s;
if (msg.length) {
Backend.addShout(socket.uid, msg, function(err, shout) {
SocketIndex.server.sockets.emit('event:shoutbox.receive', shout);
callback(null, true);
});
}
},
remove: function(socket, data, callback) {
if (data && data.sid) {
Backend.removeShout(data.sid, socket.uid, function(err, result) {
if (result === true) {
SocketIndex.server.sockets.emit('event:shoutbox.delete', {
sid: data.sid
});
}
callback(err, result);
});
}
},
edit: function(socket, data, callback) {
if (data && data.sid) {
var msg = S(data.edited).stripTags().s;
Backend.editShout(data.sid, msg, socket.uid, function(err, result) {
if (err) {
return callback(err);
}
SocketIndex.server.sockets.emit('event:shoutbox.edit', result);
result = true;
}
callback(err, result);
});
}
},
removeAll: function(socket, data, callback) {
if(!data) {
return callback(new Error('invalid-data'));
}
if (data.which === 'deleted') {
return Backend.pruneDeleted(socket.uid, callback);
} else if (data.which === 'all') {
return Backend.removeAll(socket.uid, callback);
}
return callback(null, false);
},
getUsers: function(socket, data, callback){
var users = SocketIndex.getConnectedClients();
User.getMultipleUserFields(users, ['username'], function(err, usersData) {
if(err) {
return callback(null, []);
return callback(err, true);
});
}
return callback(null, usersData);
});
},
getSettings: function(socket, data, callback) {
if (socket.uid === 0) {
return;
}
Config.settings.get({ uid: socket.uid, settings: {} }, function(err, result) {
var settings = {};
for (var i = 0, l = Config.settings.keys.length; i < l; i++) {
settings[Config.settings.keys[i]] = result.settings[Config.prefix + Config.settings.keys[i]];
},
removeAll: function(socket, data, callback) {
if(!data) {
return callback(new Error('invalid-data'));
}
callback(null, {
settings: settings,
shoutLimit: parseInt(Config.get('shoutlimit'), 10)
});
});
},
saveSetting: function(socket, data, callback) {
if (!data || !data.key || !socket.uid) {
if (data.which === 'deleted') {
return Backend.pruneDeleted(socket.uid, callback);
} else if (data.which === 'all') {
return Backend.removeAll(socket.uid, callback);
}
return callback(null, false);
},
getOriginalShout: function(socket, data, callback) {
if (data.sid && socket.uid !== 0) {
Backend.getRawShout(data.sid, function(err, shout) {
if (err) {
return callback(err);
}
return callback(null, shout.content);
});
}
},
notifyStartTyping: function(socket, data, callback) {
if (!socket.uid) {
return;
}
var uid = socket.uid;
SocketIndex.server.sockets.emit('event:shoutbox.startTyping', { uid: uid });
if (socket.listeners('disconnect').length === 0) {
socket.on('disconnect', function() {
Sockets.notifyStopTyping(socket, data, callback);
});
}
},
notifyStopTyping: function(socket, data, callback) {
if (!socket.uid) {
return;
}
var uid = socket.uid;
SocketIndex.server.sockets.emit('event:shoutbox.stopTyping', { uid: uid });
},
getSettings: Config.userSockets.getSettings,
saveSetting: Config.userSockets.saveSettings
};
function updateUidSocketIndex(socket) {
if (!socket.isBot) {
uidSocketIndex[socket.uid] = socket;
if (socket.listeners('disconnect').length === 0) {
socket.on('disconnect', function() {
delete uidSocketIndex[socket.uid];
});
}
}
var setting = {};
setting[Config.prefix + data.key] = data.value;
Config.settings.save({ uid: socket.uid, settings: setting}, callback);
},
getOriginalShout: function(socket, data, callback) {
if (data.sid && socket.uid !== 0) {
Backend.getShout(data.sid, function(err, shout) {
if (err) {
return callback(err);
}
return callback(null, shout.content);
});
}
for (var s in Commands.sockets) {
if (Commands.sockets.hasOwnProperty(s)) {
handlers[s] = Commands.sockets[s];
}
}
}
module.exports = Sockets;
Sockets.events = handlers;
Sockets.uidSocketIndex = uidSocketIndex;
})(module.exports);

@@ -1,13 +0,8 @@

var fs = require('fs'),
path = require('path'),
NodeBB = require('./lib/nodebb'),
var NodeBB = require('./lib/nodebb'),
Config = require('./lib/config'),
Sockets = require('./lib/sockets'),
ModulesSockets = NodeBB.ModulesSockets,
SocketPlugins = NodeBB.SocketPlugins,
SocketAdmin = NodeBB.SocketAdmin,
User = NodeBB.User,
db = NodeBB.db,
app;

@@ -17,25 +12,32 @@

Shoutbox.init = {
load: function(expressApp, middleware, controllers) {
Shoutbox.register = {
load: function(expressApp, middleware, controllers, callback) {
app = expressApp;
function renderGlobal(req, res, next) {
Config.api(function(data) {
res.render('shoutbox', data);
Config.getTemplateData(function(data) {
res.render(Config.plugin.id, data);
});
}
function renderAdmin(req, res, next) {
Config.api(function(data) {
res.render('shoutbox/admin', data);
Config.getTemplateData(function(data) {
res.render('admin/' + Config.plugin.id, data);
});
}
app.get('/shoutbox', middleware.buildHeader, renderGlobal);
app.get('/api/shoutbox', renderGlobal);
app.get('/admin/shoutbox', middleware.admin.buildHeader, renderAdmin);
app.get('/api/admin/shoutbox', renderAdmin);
ModulesSockets.shoutbox = Sockets;
app.get(Config.plugin.route, middleware.buildHeader, renderGlobal);
app.get('/api' + Config.plugin.route, renderGlobal);
app.get('/admin' + Config.plugin.route, middleware.admin.buildHeader, renderAdmin);
app.get('/api/admin' + Config.plugin.route, renderAdmin);
SocketPlugins[Config.plugin.id] = Sockets.events;
SocketAdmin[Config.plugin.id] = Config.adminSockets;
callback(expressApp, middleware, controllers);
},
global: {
addNavigation: function(custom_header, callback) {
if (Config.get('headerlink') === '1') {
if (Config.global.get('toggles.headerLink')) {
custom_header.navigation.push({

@@ -48,2 +50,3 @@ class: '',

}
callback(null, custom_header);

@@ -63,3 +66,3 @@ }

}
}
};

@@ -74,25 +77,29 @@ Shoutbox.widget = {

});
callback(null, widgets);
},
render: function(widget, callback) {
if (widget.uid === 0) {
return callback();
}
//Remove any container
widget.data.container = '';
if (widget.uid !== 0) {
//Currently doing this on the server -- still debating what's better
Config.settings.get({ uid: widget.uid, settings: {} }, function(err, result) {
Config.api(function(data) {
data.hiddenStyle = '';
if (result.settings[Config.prefix + 'hide'] == 1) {
data.hiddenStyle = 'display: none;';
}
app.render('shoutbox', data, callback);
});
//Currently doing this on the server -- still debating what's better
Config.user.get({ uid: widget.uid, settings: {} }, function(err, result) {
Config.getTemplateData(function(data) {
data.hiddenStyle = '';
if (parseInt(result.settings['shoutbox:toggles:hide'], 10) == 1) {
data.hiddenStyle = 'display: none;';
}
app.render('shoutbox/panel', data, callback);
});
// Client or server?
});
// Client or server?
// Config.api(function(data) {
// app.render('shoutbox', data, callback);
// });
}
}
}
};

@@ -108,12 +115,19 @@ Shoutbox.settings = {

});
},
getUserSettings: function(data, callback) {
Config.settings.get(data, callback);
Config.user.get(data, callback);
},
saveUserSettings: function(data) {
Config.settings.save(data);
Config.user.save(data);
}
}
};
Shoutbox.sounds = {
getSounds: function(sounds, callback) {
sounds.push(__dirname + '/public/sounds/shoutbox-notification.mp3');
sounds.push(__dirname + '/public/sounds/shoutbox-wobblysausage.mp3');
callback(null, sounds);
}
};
module.exports = Shoutbox;
{
"name": "nodebb-plugin-shoutbox",
"version": "0.1.0",
"version": "0.2.0",
"description": "NodeBB Shoutbox Plugin",

@@ -5,0 +5,0 @@ "main": "library.js",

@@ -8,8 +8,11 @@ {

"hooks": [
{ "hook": "action:app.load", "method": "init.load" },
{ "hook": "filter:admin.header.build", "method": "init.admin.addNavigation" },
{ "hook": "filter:header.build", "method": "init.global.addNavigation" },
{ "hook": "static:app.load", "method": "register.load" },
{ "hook": "filter:admin.header.build", "method": "register.admin.addNavigation" },
{ "hook": "filter:header.build", "method": "register.global.addNavigation" },
{ "hook": "filter:user.settings", "method": "settings.addUserSettings" },
{ "hook": "filter:user.getSettings", "method": "settings.getUserSettings" },
{ "hook": "action:user.saveSettings", "method": "settings.saveUserSettings" },
{ "hook": "filter:sounds.get", "method": "sounds.getSounds" },
{ "hook": "filter:widgets.getWidgets", "method": "widget.define" },

@@ -25,6 +28,7 @@ { "hook": "filter:widget.render:shoutbox", "method": "widget.render" }

"scripts": [
"public/js/loader.js"
"public/js/loader.js",
"public/js/lib/"
],
"templates": "./templates",
"minver": "0.4.0"
"minver": "0.5.0"
}
(function() {
var settings, wrapper, saveInterval;
$(document).ready(function() {
require(['forum/admin/settings'], function(Settings) {
Settings.prepare(function() {
prepareFeatures();
require(['settings'], function(_settings) {
settings = _settings;
wrapper = $('#shoutboxAdminForm');
settings.sync('shoutbox', wrapper, function() {
prepareFeatures(settings.get().toggles.features);
});
$('#save').click(function(event) {
event.preventDefault();
save();
});
$('#reset').click(function(event) {
event.preventDefault();
reset();
});
prepareButtons();
wrapper.on('change', function(event) {
save();
});
});
prepareButtons();
});
function prepareFeatures() {
function updateSettings() {
var features = {};
$('[data-feature]').each(function() {
var feature = $(this).data('feature');
features[feature] = {
feature: feature,
enabled: $(this).find('.fa').hasClass('fa-check-circle')
};
function save() {
clearTimeout(saveInterval);
saveInterval = setTimeout(function() {
settings.persist('shoutbox', wrapper, function() {
socket.emit('admin.plugins.shoutbox.sync');
});
$('#features-settings').val(JSON.stringify(features));
}
}, 1000);
}
function reset() {
bootbox.confirm('Are you sure you wish to reset the settings?', function(sure) {
if (sure) {
socket.emit('admin.plugins.shoutbox.getDefaults', null, function (err, data) {
settings.set('shoutbox', data, wrapper, function(){
socket.emit('admin.plugins.shoutbox.sync');
});
});
}
});
}
function prepareFeatures(featureSettings) {
function on(feature) {

@@ -28,3 +59,6 @@ var el = $('[data-feature="' + feature + '"]');

el.removeClass('disabled');
el.find('input:checkbox').prop('checked', true);
}
function off(feature) {

@@ -34,2 +68,4 @@ var el = $('[data-feature="' + feature + '"]');

el.addClass('disabled');
el.find('input:checkbox').prop('checked', false);
}

@@ -44,3 +80,3 @@

}
updateSettings();
save();
}

@@ -60,11 +96,11 @@

var saved = JSON.parse($('#features-settings').val());
for (var feature in saved) {
if (saved.hasOwnProperty(feature)) {
if (!saved[feature].enabled) {
for (var feature in featureSettings) {
if (featureSettings.hasOwnProperty(feature)) {
if (!featureSettings[feature]) {
off(feature);
} else {
on(feature);
}
}
}
updateSettings();
}

@@ -76,3 +112,3 @@

if (confirm) {
socket.emit('modules.shoutbox.removeAll', {'which':'deleted'}, function(err, result) {
socket.emit('plugins.shoutbox.removeAll', {'which':'deleted'}, function(err, result) {
if(err) {

@@ -91,3 +127,3 @@ return app.alertError(err.message);

if (confirm) {
socket.emit('modules.shoutbox.removeAll', {'which':'all'}, function(err, result) {
socket.emit('plugins.shoutbox.removeAll', {'which':'all'}, function(err, result) {
if(err) {

@@ -94,0 +130,0 @@ return app.alertError(err.message);

@@ -1,285 +0,16 @@

define(['string'], function(S) {
var sb;
(function(Shoutbox) {
var actions = [];
var Actions = {
send: {
register: function(shoutBox) {
var sendMessage = this.handle;
shoutBox.find('#shoutbox-message-input').off('keypress').on('keypress', function(e) {
if(e.which === 13 && !e.shiftKey) {
sendMessage(shoutBox);
}
});
shoutBox.find('#shoutbox-message-send-btn').off('click').on('click', function(e){
sendMessage(shoutBox);
return false;
});
},
handle: function(shoutBox) {
var msg = S(shoutBox.find('#shoutbox-message-input').val()).stripTags().trim().s;
if(msg.length) {
socket.emit(sb.config.sockets.send, { message:msg });
}
shoutBox.find('#shoutbox-message-input').val('');
}
Shoutbox.actions = {
register: function(obj) {
actions.push(obj);
},
delete: {
register: function(shoutBox) {
shoutBox.off('click', '.shoutbox-shout-option-close').on('click', '.shoutbox-shout-option-close', this.handle);
},
handle: function(e) {
var sid = $(e.currentTarget).parents('[data-sid]').data('sid');
socket.emit(sb.config.sockets.remove, { sid: sid }, function (err, result) {
if (result === true) {
app.alertSuccess('Successfully deleted shout!');
} else if (err) {
app.alertError('Error deleting shout: ' + err.message, 3000);
}
});
return false;
}
},
edit: {
register: function(shoutBox) {
var handle = this.handle;
shoutBox.off('click', '.shoutbox-shout-option-edit').on('click', '.shoutbox-shout-option-edit', function(e) {
handle(shoutBox, $(e.currentTarget).parents('[data-sid]').data('sid'));
});
shoutBox.off('dblclick', '[data-sid]').on('dblclick', '[data-sid]', function(e) {
handle(shoutBox, $(e.currentTarget).data('sid'));
});
shoutBox.find('#shoutbox-message-input').off('keyup').on('keyup', function(e) {
if(e.which === 38) {
handle(shoutBox, shoutBox.find('[data-uid="' + app.uid + '"] [data-sid]:last').data('sid'));
}
});
},
handle: function(shoutBox, sid) {
var shout = shoutBox.find('[data-sid="' + sid + '"]');
if (shout.parents('[data-uid]').data('uid') === app.uid || app.isAdmin) {
Actions.edit.editing = sid;
socket.emit(sb.config.sockets.getOriginalShout, { sid: sid }, function(err, orig) {
shoutBox.find('#shoutbox-message-send-btn').off('click').on('click', function(e){
edit(orig);
}).text('Edit');
shoutBox.find('#shoutbox-message-input').off('keyup').off('keypress').on('keypress', function(e) {
if (e.which === 13 && !e.shiftKey) {
edit(orig);
}
}).on('keyup', function(e) {
if (e.currentTarget.value.length === 0) {
Actions.edit.finish(shoutBox);
}
}).val(orig).focus().putCursorAtEnd().parent().addClass('has-warning');
});
initialize: function(shoutPanel) {
for (var a in actions) {
if (actions.hasOwnProperty(a)) {
actions[a].register(shoutPanel);
}
function edit(orig) {
var msg = S(shoutBox.find('#shoutbox-message-input').val()).stripTags().s;
if (msg === orig || msg === '' || msg === null) {
return Actions.edit.finish(shoutBox);
}
socket.emit(sb.config.sockets.edit, { sid: sid, edited: msg }, function (err, result) {
if (result === true) {
app.alertSuccess('Successfully edited shout!');
} else if (err) {
app.alertError('Error editing shout: ' + err.message, 3000);
}
Actions.edit.finish(shoutBox);
});
}
return false;
},
finish: function(shoutBox) {
var parent = shoutBox.find('#shoutbox-message-input').parent();
parent.removeClass('has-warning').find('#shoutbox-message-send-btn').removeClass('hide');
parent.find('#shoutbox-message-send-btn').text('Send');
parent.find('#shoutbox-message-input').val('');
Actions.send.register(shoutBox);
Actions.edit.register(shoutBox);
Actions.edit.editing = 0;
},
editing: 0
},
gist: {
register: function(shoutBox) {
var show = this.handle.show,
create = this.handle.create,
gistModal = $('#shoutbox-modal-gist');
shoutBox.find('#shoutbox-button-gist').off('click').on('click', function(e) {
show(gistModal);
});
gistModal.find('#shoutbox-button-create-gist-submit').off('click').on('click', function(e) {
create(gistModal.find('textarea').val(), gistModal);
});
},
handle: {
show: function(gistModal) {
gistModal.modal('show');
},
'create': function(code, gistModal) {
if (app.uid === null) {
gistModal.modal('hide');
app.alertError('Only registered users can create Gists!', 3000);
return;
}
var json = {
"description": "Gist created from BitBangers shoutbox",
"public": true,
"files": {
"file1.txt": {
"content": code
}
}
}
$.post('https://api.github.com/gists', JSON.stringify(json), function(data) {
gistModal.modal('hide');
var input = sb.base.getShoutPanel().find('#shoutbox-message-input');
var link = data.html_url;
if (input.val().length > 0) {
link = ' ' + link;
}
input.val(input.val() + link);
app.alertSuccess('Successfully created Gist!', 3000);
gistModal.find('textarea').val('');
}).fail(function(data) {
gistModal.modal('hide');
app.alertError('Error while creating Gist, try again later!', 3000);
});
}
}
},
archive: {
register: function(shoutBox) {
var handle = this.handle,
archiveModal = $('#shoutbox-archive-modal');
shoutBox.find('#shoutbox-button-archive').off('click').on('click', function(e) {
handle.show(archiveModal, handle);
});
archiveModal.find('#shoutbox-button-archive-prev').off('click').on('click', function(e) {
handle.prev(archiveModal, handle);
});
archiveModal.find('#shoutbox-button-archive-next').off('click').on('click', function(e) {
handle.next(archiveModal, handle);
});
},
handle: {
show: function(archiveModal, handle) {
archiveModal.modal('show');
if (!archiveModal.data('start')) {
archiveModal.data('start', (-(sb.config.vars.shoutLimit - 1)).toString());
archiveModal.data('end', '-1');
}
handle.get(archiveModal, handle);
},
prev: function(archiveModal, handle) {
var start = parseInt(archiveModal.data('start'), 10) - sb.config.vars.shoutLimit,
end = parseInt(archiveModal.data('end'), 10) - sb.config.vars.shoutLimit;
if (Math.abs(start) < (parseInt(sb.config.vars.lastSid, 10) + sb.config.vars.shoutLimit)) {
archiveModal.data('start', start);
archiveModal.data('end', end);
handle.get(archiveModal, handle);
}
},
next: function(archiveModal, handle) {
var start = parseInt(archiveModal.data('start'), 10) + sb.config.vars.shoutLimit,
end = parseInt(archiveModal.data('end'), 10) + sb.config.vars.shoutLimit,
startLimit = -(sb.config.vars.shoutLimit - 1);
if (start <= startLimit && end < 0) {
archiveModal.data('start', start);
archiveModal.data('end', end);
handle.get(archiveModal, handle);
}
},
get: function(archiveModal, handle) {
archiveModal.find('#shoutbox-archive-content').html('');
var start = archiveModal.data('start'),
end = archiveModal.data('end');
socket.emit(sb.config.sockets.get, { start: start, end: end }, function(err, shouts) {
for(var i = 0; i < shouts.length; i++) {
handle.addShout(archiveModal, shouts[i]);
}
archiveModal.find('.shoutbox-shout-options').remove();
});
},
addShout: function(archiveModal, shout) {
if (shout && shout.sid) {
var archiveContent = archiveModal.find('#shoutbox-archive-content');
if (parseInt(shout.fromuid, 10) === archiveContent.find('[data-uid]:last').data('uid')) {
archiveContent.find('[data-sid]:last').after(sb.utils.parseShout(shout, true));
} else {
archiveContent.append(sb.utils.parseShout(shout));
}
sb.base.scrollToBottom(archiveContent);
}
}
}
},
bug: {
register: function(shoutBox) {
shoutBox.find('#shoutbox-button-bug').off('click').on('click', this.handle);
},
handle: function(e) {
window.open('https://github.com/Schamper/nodebb-plugin-shoutbox/issues/new', '_blank').focus();
}
},
settings: {
register: function(shoutBox) {
shoutBox.off('click', '#shoutbox-settings-menu a').on('click', '#shoutbox-settings-menu a', this.handle);
},
handle: function(e) {
var el = $(e.currentTarget),
statusEl = el.find('span'),
key = el.attr('id').split('shoutbox-settings-')[1],
status = statusEl.hasClass('fa-check');
if (status) {
statusEl.removeClass('fa-check').addClass('fa-times');
status = 0;
} else {
statusEl.removeClass('fa-times').addClass('fa-check');
status = 1;
}
sb.config.settings[key] = !status;
socket.emit(sb.config.sockets.saveSettings, { key: key, value: status }, function(err, result) {
if (err || result === false) {
app.alertError('Error saving settings!');
}
});
return false;
}
},
hide: {
register: function(shoutBox) {
shoutBox.off('click', '#shoutbox-settings-hide').on('click', '#shoutbox-settings-hide', this.handle);
},
handle: function(e) {
var el = $(e.currentTarget).find('span'),
body = sb.base.getShoutPanel().find('.panel-body');
if (el.hasClass('fa-arrow-up')) {
body.slideUp();
el.removeClass('fa-arrow-up').addClass('fa-arrow-down');
sb.config.settings['hide'] = true;
} else {
body.slideDown();
el.removeClass('fa-arrow-down').addClass('fa-arrow-up');
sb.config.settings['hide'] = false;
}
socket.emit(sb.config.sockets.saveSettings, { key: 'hide', value: sb.config.settings['hide'] });
}
}
};
return function(Shoutbox) {
Shoutbox.actions = Actions;
sb = Shoutbox;
};
});
})(window.Shoutbox);

@@ -1,59 +0,86 @@

define(function() {
var sb;
(function(Shoutbox) {
var Base = {
initialize: function(url, shoutPanel) {
Base.vars.shoutPanel = shoutPanel;
if (!Shoutbox.utils.isAnon()) {
Shoutbox.utils.initialize(shoutPanel, function() {
Base.getShouts(shoutPanel);
var Base = {
load: function() {
sb.utils.checkAnon(function(isAnon) {
if(!isAnon) {
sb.utils.prepareShoutbox(Base);
}
});
//Add mentions autofill
if (typeof Mentions !== 'undefined' && typeof Mentions.addAutofill !== 'undefined') {
Mentions.addAutofill(shoutPanel.find('#shoutbox-message-input'), []);
}
//Add emoji autocomplete
function addEmoji(emoji) {
emoji.addCompletion(shoutPanel.find('#shoutbox-message-input'));
}
if (typeof emojiExtended !== 'undefined') {
addEmoji(emojiExtended);
} else {
$(window).one('emoji-extended:initialized', addEmoji);
}
if (url === 'shoutbox') {
Shoutbox.base.showUserPanel();
}
});
}
},
addShout: function(shoutBox, shout) {
addShout: function(shout, shoutPanel) {
if (shout && shout.sid) {
var shoutContent = shoutBox.find('#shoutbox-content');
if (shoutContent.find('div[class="shoutbox-shout-container"]').length === 0) {
shoutContent.html('');
}
var shoutContent = shoutPanel.find('#shoutbox-content');
// add timeString to shout
// jQuery.timeago only works properly with ISO timestamps
shout.timeString = (new Date( parseInt( shout.timestamp, 10 ) ).toISOString() );
if (parseInt(shout.fromuid, 10) === shoutContent.find('[data-uid]:last').data('uid')) {
shoutContent.find('[data-sid]:last').after(sb.utils.parseShout(shout, true));
shoutContent.find('[data-sid]:last').after(Shoutbox.utils.parseShout(shout, true));
} else {
shoutContent.append(sb.utils.parseShout(shout));
shoutContent.append(Shoutbox.utils.parseShout(shout));
}
Base.scrollToBottom(shoutContent);
sb.config.vars.lastSid = shout.sid;
// We need to update the timestring on every new activity. Shout.tpl is only parsed for the shout of a
// chain breaking user, after that only text.tpl is parsed.
var lastChainTimestamp = shoutContent.find('[data-uid="' + shout.fromuid + '"] span.timeago:last');
lastChainTimestamp.attr('title', shout.timeString);
// execute jQuery.timeago() on shout's span.timeago
if (jQuery.timeago) {
// Reset timeago to use the new timestamp
lastChainTimestamp.data('timeago', null).timeago();
}
// else span.timeago text will be empty, but timeString will appear on hover <-- see templates/shoutbox/shout.tpl
Shoutbox.utils.scrollToBottom(shoutContent);
Shoutbox.vars.lastSid = shout.sid;
}
},
getShouts: function(shoutBox) {
socket.emit(sb.config.sockets.get, function(err, shouts) {
getShouts: function(shoutPanel) {
Shoutbox.sockets.getShouts(function(err, shouts) {
if (shouts.length === 0) {
sb.utils.showEmptyMessage(shoutBox);
Shoutbox.utils.showMessage(Shoutbox.vars.messages.empty, shoutPanel);
} else {
for(var i = 0; i < shouts.length; i++) {
Base.addShout(shoutBox, shouts[i]);
Shoutbox.base.addShout(shouts[i], shoutPanel);
}
//Base.updateUserStatus(shoutBox);
}
});
},
scrollToBottom: function(shoutContent) {
if(shoutContent[0]) {
shoutContent.scrollTop(
shoutContent[0].scrollHeight - shoutContent.height()
);
}
},
updateUserStatus: function(shoutBox, uid, status) {
updateUserStatus: function(uid, status, shoutPanel) {
var getStatus = function(uid) {
socket.emit(sb.config.sockets.getUserStatus, uid, function(err, data) {
Shoutbox.sockets.getUserStatus(uid, function(err, data) {
setStatus(uid, data.status);
});
}
};
var setStatus = function(uid, status) {
shoutBox.find('[data-uid="' + uid + '"] .shoutbox-shout-avatar').removeClass().addClass('shoutbox-shout-avatar ' + status);
}
shoutPanel.find('[data-uid="' + uid + '"] .shoutbox-shout-avatar-link').removeClass().addClass('shoutbox-shout-avatar-link ' + status);
};
if (!uid) {
uid = [];
shoutBox.find('[data-uid]').each(function(index, el){
shoutPanel.find('[data-uid]').each(function(index, el){
uid.push($(el).data('uid'))

@@ -70,3 +97,3 @@ });

} else if (Array.isArray(uid)) {
for(var i = 0, l = uid.length; i < l; i++) {
for (var i = 0, l = uid.length; i < l; i++) {
getStatus(uid[i]);

@@ -79,3 +106,3 @@ }

} else if (Array.isArray(uid)) {
for(var i = 0, l = uid.length; i < l; i++) {
for (var i = 0, l = uid.length; i < l; i++) {
setStatus(uid[i], status);

@@ -87,19 +114,25 @@ }

updateUsers: function() {
socket.emit(sb.config.sockets.getUsers, { set: 'users:online', after: 0 }, function(err, data) {
var userCount = data.users.length;
var usernames = data.users.map(function(i) {
return (i.username === null ? 'Anonymous' : i.username);
});
var userString = usernames.join('; ');
Base.getUsersPanel().find('.panel-body').text(userString);
Base.getUsersPanel().find('.panel-title').text('Users (' + userCount + ')');
Shoutbox.sockets.getUsers({ set: 'users:online', after: 0 }, function(err, data) {
var userCount = data.users.length,
usernames = data.users.map(function(i) {
return (i.username === null ? 'Anonymous' : i.username);
}),
userString = usernames.join('; ');
Shoutbox.base.getUsersPanel().find('.panel-body').text(userString);
Shoutbox.base.getUsersPanel().find('.panel-title').text('Users (' + userCount + ')');
});
if(Base.userCheck === 0) {
Base.userCheck = setInterval(function() {
Base.updateUsers();
if(Shoutbox.base.userCheck === 0) {
Shoutbox.base.userCheck = setInterval(function() {
Shoutbox.base.updateUsers();
}, 10000);
}
},
showUserPanel: function() {
Base.getUsersPanel().parent().removeClass('hidden');
Base.updateUsers();
},
getShoutPanel: function() {
return $('#shoutbox');
return Base.vars.shoutPanel || $('#shoutbox');
},

@@ -110,2 +143,3 @@ getUsersPanel: function() {

vars: {
shoutPanel: null,
userCheck: 0

@@ -115,6 +149,8 @@ }

return function(Shoutbox) {
Shoutbox.base = Base;
sb = Shoutbox;
Shoutbox.base = {
initialize: Base.initialize,
addShout: Base.addShout,
getShoutPanel: Base.getShoutPanel,
updateUserStatus: Base.updateUserStatus
};
});
})(window.Shoutbox);

@@ -1,70 +0,105 @@

define(function() {
var sb;
var Sockets = {
onreceive: {
register: function() {
if (socket.listeners(sb.config.sockets.onReceive).length === 0) {
socket.on(sb.config.sockets.onReceive, this.handle);
(function(Shoutbox) {
var Messages = {
getShouts: 'plugins.shoutbox.get',
sendShout: 'plugins.shoutbox.send',
removeShout : 'plugins.shoutbox.remove',
editShout: 'plugins.shoutbox.edit',
notifyStartTyping: 'plugins.shoutbox.notifyStartTyping',
notifyStopTyping: 'plugins.shoutbox.notifyStopTyping',
getOriginalShout: 'plugins.shoutbox.getOriginalShout',
saveSettings: 'plugins.shoutbox.saveSetting',
getSettings: 'plugins.shoutbox.getSettings',
getUsers: 'user.loadMore',
getUserStatus: 'user.isOnline'
};
var Events = {
onUserStatusChange: Messages.getUserStatus,
onReceive: 'event:shoutbox.receive',
onDelete: 'event:shoutbox.delete',
onEdit: 'event:shoutbox.edit',
onStartTyping: 'event:shoutbox.startTyping',
onStopTyping: 'event:shoutbox.stopTyping'
};
var Handlers = {
onReceive: function(data) {
var shoutPanel = Shoutbox.base.getShoutPanel();
if (shoutPanel.length > 0) {
Shoutbox.base.addShout(data, shoutPanel);
if (data.fromuid !== app.uid) {
Shoutbox.utils.notify(data);
}
},
handle: function(data) {
var shoutBox = sb.base.getShoutPanel();
if (shoutBox.length > 0) {
sb.base.addShout(shoutBox, data);
if (data.fromuid !== app.uid) {
if (sb.config.getSetting('notification') === 1) {
app.alternatingTitle(sb.config.messages.alert.replace(/%u/g, data.user.username));
}
if (sb.config.getSetting('sound') === 1) {
$('#shoutbox-sounds-notification')[0].play();
}
}
}
}
},
ondelete: {
register: function() {
if (socket.listeners(sb.config.sockets.onDelete).length === 0) {
socket.on(sb.config.sockets.onDelete, this.handle);
}
},
handle: function(data) {
var par = $('[data-sid="' + data.sid + '"]').parents('[data-uid]');
if (par.find('[data-sid]').length === 1) {
par.remove();
} else {
$('[data-sid="' + data.sid + '"]').remove();
}
if (data.sid === sb.actions.edit.editing) {
sb.actions.edit.finish(sb.base.getShoutPanel());
}
onDelete: function(data) {
var selector = $('[data-sid="' + data.sid + '"]'),
par = selector.parents('[data-uid]');
if (par.find('[data-sid]').length === 1) {
par.remove();
} else {
selector.remove();
}
if (data.sid === Shoutbox.vars.editing) {
Shoutbox.actions.finishEdit(Shoutbox.base.getShoutPanel());
}
},
onedit: {
register: function() {
if (socket.listeners(sb.config.sockets.onEdit).length === 0) {
socket.on(sb.config.sockets.onEdit, this.handle);
onEdit: function(data) {
data.content = '<abbr title="edited">' + data.content + '</abbr>';
$('[data-sid="' + data.sid + '"]').replaceWith(Shoutbox.utils.parseShout(data, true));
},
onUserStatusChange: function(err, data) {
Shoutbox.base.updateUserStatus(data.uid, data.status, Shoutbox.base.getShoutPanel());
},
onStartTyping: function(data) {
$('[data-uid="' + data.uid + '"]').addClass('isTyping');
},
onStopTyping: function(data) {
$('[data-uid="' + data.uid + '"]').removeClass('isTyping');
},
defaultSocketHandler: function(message) {
this.message = message;
var self = this;
return function (data, callback) {
if (typeof data === 'function') {
callback = data;
data = null;
}
},
handle: function(data) {
data.content = $(data.content).wrapInner('<abbr title="edited"></abbr>').html();
$('[data-sid="' + data.sid + '"]').html(sb.utils.parseShout(data, true));
socket.emit(self.message, data, callback);
};
}
};
Shoutbox.sockets = {
messages: Messages,
events: Events,
registerMessage: function(handle, message) {
if (!Shoutbox.sockets.hasOwnProperty(handle)) {
Shoutbox.sockets[handle] = new Handlers.defaultSocketHandler(message);
}
},
onstatuschange: {
register: function() {
if (socket.listeners(sb.config.sockets.getUserStatus).length === 0) {
socket.on(sb.config.sockets.getUserStatus, this.handle);
registerEvent: function(event, handler) {
if (socket.listeners(event).length === 0) {
socket.on(event, handler);
}
},
initialize: function() {
for (var e in Events) {
if (Events.hasOwnProperty(e)) {
this.registerEvent(Events[e], Handlers[e]);
}
},
handle: function(err, data) {
sb.base.updateUserStatus(sb.base.getShoutPanel(), data.uid, data.status);
}
for (var m in Messages) {
if (Messages.hasOwnProperty(m)) {
this.registerMessage(m, Messages[m]);
}
}
}
};
return function(Shoutbox) {
Shoutbox.sockets = Sockets;
sb = Shoutbox;
};
});
})(window.Shoutbox);

@@ -1,6 +0,14 @@

define(function() {
var sb, shoutTpl, textTpl;
(function(Shoutbox) {
var shoutTpl, textTpl,
sounds;
require(['sounds'], function(s) {
sounds = s;
});
var Utils = {
init: function(callback) {
initialize: function(shoutPanel, callback) {
Shoutbox.sockets.initialize();
Shoutbox.actions.initialize(shoutPanel);
if (!shoutTpl || !textTpl) {

@@ -11,7 +19,7 @@ window.ajaxify.loadTemplate('shoutbox/shout', function(shout) {

textTpl = text;
callback();
Shoutbox.settings.load(shoutPanel, callback);
});
});
} else {
callback();
Shoutbox.settings.load(shoutPanel, callback);
}

@@ -24,85 +32,55 @@ },

},
prepareShoutbox: function() {
Utils.getSettings(function() {
var shoutBox = sb.base.getShoutPanel();
//if (shoutBox.length > 0 && Config.settings.hide !== 1) {
// shoutBox.parents('.shoutbox-row').removeClass('hide');
if (shoutBox.length > 0) {
Utils.parseSettings(shoutBox);
Utils.registerHandlers(shoutBox);
sb.base.getShouts(shoutBox);
scrollToBottom: function(shoutContent) {
if (shoutContent[0]) {
var lastShoutHeight = $('[data-sid]:last').height(),
scrollHeight = Utils.getScrollHeight(shoutContent) - lastShoutHeight;
if (scrollHeight < Shoutbox.vars.scrollBreakpoint) {
shoutContent.scrollTop(
shoutContent[0].scrollHeight - shoutContent.height()
);
}
});
}
},
getSettings: function(callback) {
socket.emit(sb.config.sockets.getSettings, function(err, settings) {
sb.config.settings = settings.settings;
sb.config.vars.shoutLimit = settings.shoutLimit;
if(callback) {
callback();
}
});
},
parseSettings: function(shoutBox) {
var settings = sb.config.settings;
if (!settings) {
return;
getScrollHeight: function(shoutContent) {
if (shoutContent[0]) {
var padding = shoutContent.css('padding-top').replace('px', '') + shoutContent.css('padding-bottom').replace('px', '');
return (((shoutContent[0].scrollHeight - shoutContent.scrollTop()) - shoutContent.height()) - padding);
} else {
return -1;
}
for(var key in settings) {
if (settings.hasOwnProperty(key)) {
var value = settings[key];
var el = shoutBox.find('#shoutbox-settings-' + key + ' span');
// Not the best way but it'll have to do for now
if (key !== 'hide') {
if (value === 1) {
el.removeClass('fa-times').addClass('fa-check');
} else {
el.removeClass('fa-check').addClass('fa-times');
}
} else {
if (value == 1) {
el.removeClass('fa-arrow-up').addClass('fa-arrow-down');
} else {
el.removeClass('fa-arrow-down').addClass('fa-arrow-up');
}
}
}
}
},
registerHandlers: function(shoutBox) {
Utils.addActionHandlers(shoutBox);
Utils.addSocketHandlers();
isAnon: function() {
return app.uid === 0;
},
addActionHandlers: function(shoutBox) {
var actions = sb.actions;
for (var a in actions) {
if (actions.hasOwnProperty(a)) {
actions[a].register(shoutBox);
}
}
showMessage: function(message) {
$('#shoutbox-content-overlay').find('span').html(message).parent().addClass('active');
},
addSocketHandlers: function() {
var sockets = sb.sockets;
for (var s in sockets) {
if (sockets.hasOwnProperty(s)) {
sockets[s].register();
}
}
closeMessage: function() {
$('#shoutbox-content-overlay').removeClass('active');
},
checkAnon: function(callback) {
if (app.uid === 0) {
return callback(true);
notify: function(data) {
if (parseInt(Shoutbox.settings.get('toggles.notification'), 10) === 1) {
app.alternatingTitle(Shoutbox.vars.messages.alert.replace(/%u/g, data.user.username));
}
return callback(false);
if (parseInt(Shoutbox.settings.get('toggles.sound'), 10) === 1) {
Shoutbox.utils.playSound('notification');
}
},
showEmptyMessage: function(shoutBox) {
shoutBox.find('#shoutbox-content').html(Config.messages.empty);
playSound: function(sound) {
sounds.playFile('shoutbox-' + sound + '.mp3');
}
};
return function(Shoutbox) {
Shoutbox.utils = Utils;
sb = Shoutbox;
Shoutbox.utils = {
initialize: Utils.initialize,
parseShout: Utils.parseShout,
scrollToBottom: Utils.scrollToBottom,
getScrollHeight: Utils.getScrollHeight,
showMessage: Utils.showMessage,
isAnon: Utils.isAnon,
notify: Utils.notify,
playSound: Utils.playSound
};
});
})(window.Shoutbox);

@@ -1,11 +0,13 @@

$(document).ready(function() {
$(window).on('action:ajaxify.end', function(e, data) {
if (data.url === "" || data.url === "shoutbox") {
require([
'plugins/nodebb-plugin-shoutbox/public/js/lib/shoutbox.js'
], function(shoutBox) {
shoutBox.init(data.url);
});
(function() {
$(window).on('action:widgets.loaded', function(e, data) {
if ($('#shoutbox').length > 0) {
Shoutbox.init(data.url);
}
});
});
window.Shoutbox = {
init: function(url) {
Shoutbox.base.initialize(url, $('#shoutbox'));
}
};
})();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc