Merge branch 'master' into notifications_page

v1.18.x
Julian Lam 12 years ago
commit db2917193e

@ -21,7 +21,12 @@ var socket,
socket.socket.connect(); socket.socket.connect();
}, 200); }, 200);
} else { } else {
socket = io.connect(RELATIVE_PATH); var max_reconnection_attemps = 5;
var reconnection_delay = 200;
socket = io.connect(RELATIVE_PATH, {
'max reconnection attempts': max_reconnection_attemps,
'reconnection delay': reconnection_delay
});
var reconnecting = false, var reconnecting = false,
reconnectEl, reconnectTimer; reconnectEl, reconnectTimer;
@ -59,7 +64,13 @@ var socket,
socket.socket.connect(); socket.socket.connect();
}); });
socket.on('reconnecting', function (data) { socket.on('reconnecting', function (data, attempt) {
if(attempt == max_reconnection_attemps) {
socket.socket.reconnectionAttempts = 0;
socket.socket.reconnectionDelay = reconnection_delay;
return;
}
if (!reconnectEl) reconnectEl = $('#reconnect'); if (!reconnectEl) reconnectEl = $('#reconnect');
reconnecting = true; reconnecting = true;

@ -58,9 +58,10 @@
$('#search-button').show(); $('#search-button').show();
var userLabel = loggedInMenu.find('#user_label'); var userLabel = loggedInMenu.find('#user_label');
if (userLabel.length) { if (userLabel.length) {
if (data['userslug']) if (data['userslug'])
userLabel.attr('href', '/user/' + data['userslug']); userLabel.find('#user-profile-link').attr('href', '/user/' + data['userslug']);
if (data['picture']) if (data['picture'])
userLabel.find('img').attr('src', data['picture']); userLabel.find('img').attr('src', data['picture']);
if (data['username']) if (data['username'])
@ -87,7 +88,7 @@
} }
$('#main-nav a,#right-menu a').off('click').on('click', function() { $('#main-nav a,#user-control-list a,#logged-out-menu .dropdown-menu a').off('click').on('click', function() {
if($('.navbar .navbar-collapse').hasClass('in')) if($('.navbar .navbar-collapse').hasClass('in'))
$('.navbar-header button').click(); $('.navbar-header button').click();
}); });

@ -129,6 +129,23 @@
return tags; return tags;
}, },
buildLinkTags: function(tagsArr) {
var tags = '',
tag;
for (var x = 0, numTags = tagsArr.length; x < numTags; x++) {
if (tags.length > 0) tags += "\n\t";
tag = '<link';
for (y in tagsArr[x]) {
tag += ' ' + y + '="' + tagsArr[x][y] + '"';
}
tag += ' />';
tags += tag;
}
return tags;
},
refreshTitle: function(url) { refreshTitle: function(url) {
if (!url) { if (!url) {
var a = document.createElement('a'); var a = document.createElement('a');

@ -10,6 +10,8 @@
<input type="text" class="form-control" placeholder="A short description about your community" data-field="description" /><br /> <input type="text" class="form-control" placeholder="A short description about your community" data-field="description" /><br />
<label>Site Keywords</label> <label>Site Keywords</label>
<input type="text" class="form-control" placeholder="Keywords describing your community, comma-seperated" data-field="keywords" /><br /> <input type="text" class="form-control" placeholder="Keywords describing your community, comma-seperated" data-field="keywords" /><br />
<label>Site Logo</label>
<input type="text" class="form-control" placeholder="Path to a logo to display on forum header" data-field="brand:logo" /><br />
<label>Imgur Client ID</label> <label>Imgur Client ID</label>
<input type="text" class="form-control" placeholder="Imgur ClientID for image uploads" data-field="imgurClientID" /><br /> <input type="text" class="form-control" placeholder="Imgur ClientID for image uploads" data-field="imgurClientID" /><br />
<label>Maximum User Image Size</label> <label>Maximum User Image Size</label>

@ -5,6 +5,7 @@
{meta_tags} {meta_tags}
<link href="{cssSrc}" rel="stylesheet" media="screen"> <link href="{cssSrc}" rel="stylesheet" media="screen">
<link rel="stylesheet" href="{relative_path}/vendor/fontawesome/css/font-awesome.min.css"> <link rel="stylesheet" href="{relative_path}/vendor/fontawesome/css/font-awesome.min.css">
{link_tags}
<!-- BEGIN pluginCSS --> <!-- BEGIN pluginCSS -->
<link rel="stylesheet" href="{pluginCSS.path}"> <link rel="stylesheet" href="{pluginCSS.path}">
<!-- END pluginCSS --> <!-- END pluginCSS -->
@ -40,10 +41,15 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<div>
<a href="/">
<img class="{brand:logo:display} forum-logo" src="{relative_path}/{brand:logo}" />
</a>
<a href="/"> <a href="/">
<h1 class="navbar-brand forum-title">{title}</h1> <h1 class="navbar-brand forum-title">{title}</h1>
</a> </a>
</div> </div>
</div>
<div class="navbar-collapse collapse navbar-ex1-collapse"> <div class="navbar-collapse collapse navbar-ex1-collapse">
<ul id="main-nav" class="nav navbar-nav"> <ul id="main-nav" class="nav navbar-nav">
@ -72,6 +78,18 @@
<a href="#" id="reconnect"></a> <a href="#" id="reconnect"></a>
</li> </li>
<li>
<form id="search-form" class="navbar-form navbar-right hidden-xs" role="search" method="GET" action="">
<div class="hide" id="search-fields">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" name="query" value="">
</div>
<button type="submit" class="btn btn-default hide">[[global:search]]</button>
</div>
<button id="search-button" type="button" class="btn btn-link"><i class="icon-search"></i></button>
</form>
</li>
<li id="notifications-list" class="notifications dropdown text-center hidden-xs"> <li id="notifications-list" class="notifications dropdown text-center hidden-xs">
<a class="dropdown-toggle" data-toggle="dropdown" href="#" id="notif_dropdown"><i class="icon-circle-blank"></i></a> <a class="dropdown-toggle" data-toggle="dropdown" href="#" id="notif_dropdown"><i class="icon-circle-blank"></i></a>
<ul id="notif-list" class="dropdown-menu" aria-labelledby="notif_dropdown"> <ul id="notif-list" class="dropdown-menu" aria-labelledby="notif_dropdown">
@ -81,36 +99,35 @@
</ul> </ul>
</li> </li>
<li> <li id="user_label" class="dropdown">
<a id="user_label" href=""> <a class="dropdown-toggle" data-toggle="dropdown" href="#" id="user_dropdown">
<img src=""/> <img src=""/>
<span></span>
</a> </a>
<ul id="user-control-list" class="dropdown-menu" aria-labelledby="user_dropdown">
<li>
<a id="user-profile-link" href=""><span>Profile</span></a>
</li> </li>
<li id="logout-link"> <li id="logout-link">
<a href="#">Log out</a> <a href="#">Log out</a>
</li> </li>
</ul>
</li>
<form id="search-form" class="navbar-form navbar-right hidden-xs" role="search" method="GET" action="">
<div class="hide" id="search-fields">
<div class="form-group">
<input type="text" class="form-control" placeholder="Search" name="query" value="">
</div>
<button type="submit" class="btn btn-default hide">[[global:search]]</button>
</div>
<button id="search-button" type="button" class="btn btn-link"><i class="icon-search"></i></button>
</form>
</ul> </ul>
<ul id="logged-out-menu" class="nav navbar-nav navbar-right"> <ul id="logged-out-menu" class="nav navbar-nav navbar-right">
<li id="register-link"> <li>
<a class="dropdown-toggle" data-toggle="dropdown" href="#" id="loggedout_dropdown"><i class="icon-signin"></i></a>
<ul class="dropdown-menu" aria-labelledby="loggedout_dropdown">
<li>
<a href="/register">Register</a> <a href="/register">Register</a>
</li> </li>
<li id="login-link"> <li>
<a href="/login">Login</a> <a href="/login">Login</a>
</li> </li>
</ul> </ul>
</li>
</ul>
<div class="pagination-block"> <div class="pagination-block">
<i class="icon-upload pointer"></i> <i class="icon-upload pointer"></i>

@ -61,9 +61,20 @@ var RDB = require('./redis.js'),
PostTools.edit = function(uid, pid, title, content) { PostTools.edit = function(uid, pid, title, content) {
var success = function() { var success = function() {
posts.setPostField(pid, 'content', content); async.waterfall([
function(next) {
posts.setPostField(pid, 'edited', Date.now()); posts.setPostField(pid, 'edited', Date.now());
next(null);
},
function(next) {
posts.setPostField(pid, 'editor', uid); posts.setPostField(pid, 'editor', uid);
next(null);
},
function(next) {
posts.setPostField(pid, 'content', content);
next(null);
}
]);
postSearch.remove(pid, function() { postSearch.remove(pid, function() {
postSearch.index(content, pid); postSearch.index(content, pid);

@ -24,9 +24,16 @@ var RDB = require('./redis.js'),
RDB.handle(err); RDB.handle(err);
if (pids.length) { if (pids.length) {
plugins.fireHook('filter:post.getTopic', pids, function(err, posts) {
if (!err & 0 < posts.length) {
Posts.getPostsByPids(pids, function(err, posts) { Posts.getPostsByPids(pids, function(err, posts) {
plugins.fireHook('action:post.gotTopic', posts);
callback(posts); callback(posts);
}); });
} else {
callback(posts);
}
});
} else { } else {
callback([]); callback([]);
} }
@ -131,6 +138,7 @@ var RDB = require('./redis.js'),
}); });
} }
// TODO: this function is never called except from some debug route. clean up?
Posts.getPostData = function(pid, callback) { Posts.getPostData = function(pid, callback) {
RDB.hgetall('post:' + pid, function(err, data) { RDB.hgetall('post:' + pid, function(err, data) {
if (err === null) { if (err === null) {
@ -146,7 +154,14 @@ var RDB = require('./redis.js'),
Posts.getPostFields = function(pid, fields, callback) { Posts.getPostFields = function(pid, fields, callback) {
RDB.hmgetObject('post:' + pid, fields, function(err, data) { RDB.hmgetObject('post:' + pid, fields, function(err, data) {
if (err === null) { if (err === null) {
// TODO: I think the plugins system needs an optional 'parameters' paramter so I don't have to do this:
data = data || {};
data.pid = pid;
data.fields = fields;
plugins.fireHook('filter:post.getFields', data, function(err, data) {
callback(data); callback(data);
});
} else { } else {
console.log(err); console.log(err);
} }
@ -155,15 +170,28 @@ var RDB = require('./redis.js'),
Posts.getPostField = function(pid, field, callback) { Posts.getPostField = function(pid, field, callback) {
RDB.hget('post:' + pid, field, function(err, data) { RDB.hget('post:' + pid, field, function(err, data) {
if (err === null) if (err === null) {
// TODO: I think the plugins system needs an optional 'parameters' paramter so I don't have to do this:
data = data || {};
data.pid = pid;
data.field = field;
plugins.fireHook('filter:post.getField', data, function(err, data) {
callback(data); callback(data);
else });
} else {
console.log(err); console.log(err);
}
}); });
} }
Posts.setPostField = function(pid, field, value) { Posts.setPostField = function(pid, field, value, done) {
RDB.hset('post:' + pid, field, value); RDB.hset('post:' + pid, field, value);
plugins.fireHook('action:post.setField', {
'pid': pid,
'field': field,
'value': value
}, done);
} }
Posts.getPostsByPids = function(pids, callback) { Posts.getPostsByPids = function(pids, callback) {
@ -400,14 +428,18 @@ var RDB = require('./redis.js'),
} }
Posts.getPostsByUid = function(uid, start, end, callback) { Posts.getPostsByUid = function(uid, start, end, callback) {
user.getPostIds(uid, start, end, function(pids) { user.getPostIds(uid, start, end, function(pids) {
if (pids && pids.length) { if (pids && pids.length) {
plugins.fireHook('filter:post.getTopic', pids, function(err, posts) {
if (!err & 0 < posts.length) {
Posts.getPostsByPids(pids, function(err, posts) { Posts.getPostsByPids(pids, function(err, posts) {
plugins.fireHook('action:post.gotTopic', posts);
callback(posts); callback(posts);
}); });
} else {
callback(posts);
}
});
} else } else
callback([]); callback([]);
}); });

@ -303,7 +303,7 @@ var RDB = require('./redis.js'),
pids.reverse(); pids.reverse();
async.detectSeries(pids, function(pid, next) { async.detectSeries(pids, function(pid, next) {
RDB.hget('post:' + pid, 'deleted', function(err, deleted) { posts.getPostField(pid, 'deleted', function(deleted) {
if (deleted === '0') next(true); if (deleted === '0') next(true);
else next(false); else next(false);
}); });

@ -69,14 +69,18 @@ var express = require('express'),
content: meta.config['keywords'] || '' content: meta.config['keywords'] || ''
}], }],
metaString = utils.buildMetaTags(defaultMetaTags.concat(options.metaTags || [])), metaString = utils.buildMetaTags(defaultMetaTags.concat(options.metaTags || [])),
linkTags = utils.buildLinkTags(options.linkTags || []),
templateValues = { templateValues = {
cssSrc: meta.config['theme:src'] || nconf.get('relative_path') + '/vendor/bootstrap/css/bootstrap.min.css', cssSrc: meta.config['theme:src'] || nconf.get('relative_path') + '/vendor/bootstrap/css/bootstrap.min.css',
pluginCSS: plugins.cssFiles.map(function(file) { return { path: file } }), pluginCSS: plugins.cssFiles.map(function(file) { return { path: file } }),
title: meta.config.title || 'NodeBB', title: meta.config.title || '',
'brand:logo': meta.config['brand:logo'] || '',
'brand:logo:display': meta.config['brand:logo']?'':'hide',
browserTitle: meta.config.title || 'NodeBB', browserTitle: meta.config.title || 'NodeBB',
csrf: options.res.locals.csrf_token, csrf: options.res.locals.csrf_token,
relative_path: nconf.get('relative_path'), relative_path: nconf.get('relative_path'),
meta_tags: metaString, meta_tags: metaString,
link_tags: linkTags,
clientScripts: clientScripts, clientScripts: clientScripts,
navigation: custom_header.navigation navigation: custom_header.navigation
}; };
@ -425,7 +429,18 @@ var express = require('express'),
}, { }, {
property: 'article:section', property: 'article:section',
content: topicData.category_name content: topicData.category_name
}] }],
linkTags: [
{
rel: 'alternate',
type: 'application/rss+xml',
href: nconf.get('url') + 'topic/' + tid + '.rss'
},
{
rel: 'up',
href: nconf.get('url') + 'category/' + topicData.category_slug
}
]
}, function (err, header) { }, function (err, header) {
next(err, { next(err, {
header: header, header: header,
@ -494,7 +509,18 @@ var express = require('express'),
}, { }, {
property: "og:type", property: "og:type",
content: 'website' content: 'website'
}] }],
linkTags: [
{
rel: 'alternate',
type: 'application/rss+xml',
href: nconf.get('url') + 'category/' + cid + '.rss'
},
{
rel: 'up',
href: nconf.get('url')
}
]
}, function (err, header) { }, function (err, header) {
next(err, { next(err, {
header: header, header: header,

Loading…
Cancel
Save