Merge commit '449352d8996b4c98be67052fbb5b68fdc65cd0f2' into v1.x.x

This commit is contained in:
Misty (Bot)
2017-03-16 18:57:33 +00:00
500 changed files with 12164 additions and 9225 deletions

View File

@@ -1,5 +1,4 @@
node_modules/
public/src/nodebb.min.js
*.sublime-project
*.sublime-workspace
.project
@@ -10,8 +9,6 @@ logs/
/public/uploads
/public/sounds
/public/vendor
/public/nodebb.min.js
/public/acp.min.js
/public/src/modules/string.js
.idea/
.vscode/
@@ -19,3 +16,4 @@ logs/
*.iws
/coverage
/build
.eslintrc

128
.eslintrc Normal file
View File

@@ -0,0 +1,128 @@
{
"extends": "airbnb-base",
"parserOptions": {
"sourceType": "script"
},
"rules": {
// Customized
"handle-callback-err": [ "error","^(e$|(e|(.*(_e|E)))rr)" ],
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "never"
}],
"no-empty": ["error", { "allowEmptyCatch": true }],
"no-underscore-dangle": "off",
"newline-per-chained-call": "off",
"no-console": "off",
"no-mixed-operators": ["error", { "allowSamePrecedence": true }],
"strict": ["error", "global"],
"consistent-return": "off",
"func-names": "off",
"no-tabs": "off",
"indent": ["error", "tab"],
"no-eq-null": "off",
"camelcase": "off",
"no-new": "off",
"no-shadow": "off",
"no-use-before-define": ["error", "nofunc"],
"no-prototype-builtins": "off",
"new-cap": "off",
"no-plusplus": ["error", { "allowForLoopAfterthoughts": true }],
// ES6
"prefer-rest-params": "off",
"prefer-spread": "off",
"prefer-arrow-callback": "off",
"prefer-template": "off",
"no-var": "off",
"object-shorthand": "off",
"vars-on-top": "off",
// TODO
"import/no-unresolved": "off",
"import/no-extraneous-dependencies": "off",
"import/no-dynamic-require": "off",
"import/newline-after-import": "off",
"no-bitwise": "off",
"global-require": "off",
"max-len": "off",
"no-param-reassign": "off",
"no-restricted-syntax": "off",
"no-script-url": "off",
"default-case": "off",
// "no-multi-assign": "off",
// "linebreak-style": "off",
// "one-var": "off",
// "no-undef": "off",
// "max-nested-callbacks": "off",
// "no-mixed-requires": "off",
// "brace-style": "off",
// "max-statements-per-line": "off",
// "no-unused-vars": "off",
// "no-mixed-spaces-and-tabs": "off",
// "no-useless-concat": "off",
// "require-jsdoc": "off",
// "eqeqeq": "off",
// "no-negated-condition": "off",
// "one-var-declaration-per-line": "off",
// "no-lonely-if": "off",
// "radix": "off",
// "no-else-return": "off",
// "no-useless-escape": "off",
// "block-scoped-var": "off",
// "operator-assignment": "off",
// "yoda": "off",
// "no-loop-func": "off",
// "no-void": "off",
// "valid-jsdoc": "off",
// "no-cond-assign": "off",
// "no-redeclare": "off",
// "no-unreachable": "off",
// "no-nested-ternary": "off",
// "operator-linebreak": "off",
// "guard-for-in": "off",
// "no-unneeded-ternary": "off",
// "no-sequences": "off",
// "no-extend-native": "off",
// "no-shadow-restricted-names": "off",
// "no-extra-boolean-cast": "off",
// "no-path-concat": "off",
// "no-unused-expressions": "off",
// "no-return-assign": "off",
// "no-restricted-modules": "off",
// "object-curly-spacing": "off",
// "indent": "off",
// "padded-blocks": "off",
// "eol-last": "off",
// "lines-around-directive": "off",
// "strict": "off",
// "comma-dangle": "off",
// "no-multi-spaces": "off",
// "quotes": "off",
// "keyword-spacing": "off",
// "no-mixed-operators": "off",
// "comma-spacing": "off",
// "no-trailing-spaces": "off",
// "key-spacing": "off",
// "no-multiple-empty-lines": "off",
// "spaced-comment": "off",
// "space-in-parens": "off",
// "block-spacing": "off",
// "quote-props": "off",
// "space-unary-ops": "off",
// "no-empty": "off",
// "dot-notation": "off",
// "func-call-spacing": "off",
// "array-bracket-spacing": "off",
// "object-property-newline": "off",
// "no-continue": "off",
// "no-extra-semi": "off",
// "no-spaced-func": "off",
// "no-useless-return": "off"
}
}

View File

@@ -1,111 +0,0 @@
{
"extends": "airbnb",
"rules": {
"handle-callback-err": [ "error","^(e$|(e|(.*(_e|E)))rr)" ],
"linebreak-style": "off",
"import/no-unresolved": "off",
"import/no-extraneous-dependencies": "off",
"one-var": "off",
"no-undef": "off",
"max-len": "off",
"no-new": "off",
"max-nested-callbacks": "off",
"no-mixed-requires": "off",
"brace-style": "off",
"max-statements-per-line": "off",
"no-unused-vars": "off",
"no-mixed-spaces-and-tabs": "off",
"no-useless-concat": "off",
"require-jsdoc": "off",
"eqeqeq": "off",
"camelcase": "off",
"no-negated-condition": "off",
"one-var-declaration-per-line": "off",
"new-cap": "off",
"no-lonely-if": "off",
"radix": "off",
"no-else-return": "off",
"no-useless-escape": "off",
"block-scoped-var": "off",
"operator-assignment": "off",
"default-case": "off",
"yoda": "off",
"no-use-before-define": "off",
"no-loop-func": "off",
"no-void": "off",
"valid-jsdoc": "off",
"o-eq-null": "off",
"no-cond-assign": "off",
"no-eq-null": "off",
"no-redeclare": "off",
"no-unreachable": "off",
"no-nested-ternary": "off",
"operator-linebreak": "off",
"guard-for-in": "off",
"no-unneeded-ternary": "off",
"no-sequences": "off",
"no-extend-native": "off",
"no-shadow-restricted-names": "off",
"no-extra-boolean-cast": "off",
"no-script-url": "off",
"no-path-concat": "off",
"no-unused-expressions": "off",
"no-restricted-module": "off",
"no-return-assign": "off",
"no-restricted-modules": "off",
"no-tabs": "off",
"indent": "off",
"func-names": "off",
"prefer-arrow-callback": "off",
"object-curly-spacing": "off",
"no-var": "off",
"no-shadow": "off",
"prefer-template": "off",
"padded-blocks": "off",
"eol-last": "off",
"lines-around-directive": "off",
"no-restricted-syntax": "off",
"vars-on-top": "off",
"no-prototype-builtins": "off",
"object-shorthand": "off",
"no-param-reassign": "off",
"consistent-return": "off",
"strict": "off",
"comma-dangle": "off",
"no-multi-spaces": "off",
"quotes": "off",
"keyword-spacing": "off",
"no-plusplus": "off",
"no-mixed-operators": "off",
"comma-spacing": "off",
"global-require": "off",
"no-trailing-spaces": "off",
"key-spacing": "off",
"import/newline-after-import": "off",
"no-underscore-dangle": "off",
"prefer-spread": "off",
"no-multiple-empty-lines": "off",
"spaced-comment": "off",
"prefer-rest-params": "off",
"space-in-parens": "off",
"block-spacing": "off",
"quote-props": "off",
"no-console": "off",
"space-unary-ops": "off",
"import/no-dynamic-require": "off",
"no-bitwise": "off",
"no-empty": "off",
"array-bracket-spacin": "off",
"dot-notation": "off",
"func-call-spacing": "off",
"newline-per-chained-call": "off",
"newline-per-chained-call": "off",
"array-bracket-spacing": "off",
"object-property-newline": "off",
"no-continue": "off",
"no-extra-semi": "off",
"no-spaced-func": "off",
"no-useless-return": "off"
}
}

View File

@@ -1,6 +1,10 @@
# Submitting a Pull Request to NodeBB?
First of all, thank you! Please consider this [style guide](https://docs.nodebb.org/en/latest/contributing/style-guide.html) when submitting your changes. Also, please join our [community](https://community.nodebb.org) to meet other NodeBB developers and designers :)
First of all, thank you! Before submission, please run `npm test` to lint and run the automated NodeBB tests. If everything passes, you're good to go. If you have any errors, please fix them and re-run `npm test` to make sure there aren't any others.
## Styleguide and linting
NodeBB mostly conforms to the [AirBnB Javascript style guide](https://github.com/airbnb/javascript#readme). If you're running into a lot of ESlint errors, you may want to install an editor plugin to display them in real time.
## Contributor License Agreement
@@ -51,12 +55,13 @@ $ git rev-parse HEAD
If you have downloaded the `.zip` or `.tar.gz` packages from GitHub (or elsewhere), please let us know.
## Provide theme versions if issue is related to the theme/display
Use `npm ls` to list the versions of the theme you're using. In this example, we're running the Persona theme, which depends on the Vanilla theme.
``` bash
$ npm ls nodebb-theme-vanilla nodebb-theme-lavender
nodebb@0.7.0-dev /home/julian/Projects/nodebb/forum
├── nodebb-theme-lavender@0.2.13
└── nodebb-theme-vanilla@0.2.35
$ npm ls nodebb-theme-vanilla nodebb-theme-persona
nodebb@1.4.3 /path/to/nodebb
+-- nodebb-theme-persona@4.2.4
`-- nodebb-theme-vanilla@5.2.0
```
## Attempt to use `git bisect`

1
.gitignore vendored
View File

@@ -57,3 +57,4 @@ tx.exe
coverage
build
*.log

View File

@@ -1,8 +1,10 @@
"use strict";
'use strict';
var fork = require('child_process').fork;
var env = process.env;
var worker, updateWorker, initWorker;
var worker;
var updateWorker;
var initWorker;
var incomplete = [];
var running = 0;
@@ -44,15 +46,13 @@ module.exports = function (grunt) {
if (updateWorker) {
updateWorker.kill('SIGKILL');
}
updateWorker = fork('app.js', updateArgs, {
env: env
});
++running;
updateWorker = fork('app.js', updateArgs, { env: env });
running += 1;
updateWorker.on('exit', function () {
--running;
running -= 1;
if (running === 0) {
worker = fork('app.js', args, {
env: env
env: env,
});
worker.on('message', function () {
if (incomplete.length) {
@@ -74,17 +74,17 @@ module.exports = function (grunt) {
'public/*.less',
'node_modules/nodebb-*/*.less', 'node_modules/nodebb-*/**/*.less',
'!node_modules/nodebb-*/node_modules/**',
'!node_modules/nodebb-*/.git/**'
'!node_modules/nodebb-*/.git/**',
],
options: {
interval: 1000
}
interval: 1000,
},
},
lessUpdated_Admin: {
files: ['public/**/*.less'],
options: {
interval: 1000
}
interval: 1000,
},
},
clientUpdated: {
files: [
@@ -92,28 +92,28 @@ module.exports = function (grunt) {
'node_modules/nodebb-*/*.js', 'node_modules/nodebb-*/**/*.js',
'!node_modules/nodebb-*/node_modules/**',
'node_modules/templates.js/lib/templates.js',
'!node_modules/nodebb-*/.git/**'
'!node_modules/nodebb-*/.git/**',
],
options: {
interval: 1000
}
interval: 1000,
},
},
serverUpdated: {
files: ['*.js', 'install/*.js', 'src/**/*.js'],
options: {
interval: 1000
}
interval: 1000,
},
},
templatesUpdated: {
files: [
'src/views/**/*.tpl',
'node_modules/nodebb-*/*.tpl', 'node_modules/nodebb-*/**/*.tpl',
'!node_modules/nodebb-*/node_modules/**',
'!node_modules/nodebb-*/.git/**'
'!node_modules/nodebb-*/.git/**',
],
options: {
interval: 1000
}
interval: 1000,
},
},
langUpdated: {
files: [
@@ -127,10 +127,10 @@ module.exports = function (grunt) {
'!node_modules/nodebb-*/theme.json',
],
options: {
interval: 1000
}
interval: 1000,
},
},
}
},
});
grunt.loadNpmTasks('grunt-contrib-watch');
@@ -140,16 +140,16 @@ module.exports = function (grunt) {
if (grunt.option('skip')) {
worker = fork('app.js', args, {
env: env
env: env,
});
} else {
initWorker = fork('app.js', initArgs, {
env: env
env: env,
});
initWorker.on('exit', function () {
worker = fork('app.js', args, {
env: env
env: env,
});
});
}

21
app.js
View File

@@ -17,8 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
"use strict";
/*global require, global, process*/
'use strict';
var nconf = require('nconf');
nconf.argv().env('__');
@@ -37,11 +36,11 @@ winston.add(winston.transports.Console, {
colorize: true,
timestamp: function () {
var date = new Date();
return (!!nconf.get('json-logging')) ? date.toJSON() : date.getDate() + '/' + (date.getMonth() + 1) + ' ' + date.toTimeString().substr(0,8) + ' [' + global.process.pid + ']';
return nconf.get('json-logging') ? date.toJSON() : date.getDate() + '/' + (date.getMonth() + 1) + ' ' + date.toTimeString().substr(0, 8) + ' [' + global.process.pid + ']';
},
level: nconf.get('log-level') || (global.env === 'production' ? 'info' : 'verbose'),
json: (!!nconf.get('json-logging')),
stringify: (!!nconf.get('json-logging'))
stringify: (!!nconf.get('json-logging')),
});
@@ -75,7 +74,7 @@ if (nconf.get('setup') || nconf.get('install')) {
} else if (nconf.get('reset')) {
async.waterfall([
async.apply(require('./src/reset').reset),
async.apply(require('./src/meta/build').buildAll)
async.apply(require('./src/meta/build').buildAll),
], function (err) {
process.exit(err ? 1 : 0);
});
@@ -93,7 +92,7 @@ function loadConfig(callback) {
winston.verbose('* using configuration stored in: %s', configFile);
nconf.file({
file: configFile
file: configFile,
});
nconf.defaults({
@@ -101,7 +100,7 @@ function loadConfig(callback) {
themes_path: path.join(__dirname, 'node_modules'),
upload_path: 'public/uploads',
views_dir: path.join(__dirname, 'build/public/templates'),
version: pkg.version
version: pkg.version,
});
if (!nconf.get('isCluster')) {
@@ -113,7 +112,7 @@ function loadConfig(callback) {
nconf.set('themes_path', path.resolve(__dirname, nconf.get('themes_path')));
nconf.set('core_templates_path', path.join(__dirname, 'src/views'));
nconf.set('base_templates_path', path.join(nconf.get('themes_path'), 'nodebb-theme-persona/templates'));
nconf.set('upload_path', path.resolve(nconf.get('base_dir'), nconf.get('upload_path')));
if (nconf.get('url')) {
@@ -149,14 +148,14 @@ function setup() {
async.series([
async.apply(install.setup),
async.apply(loadConfig),
async.apply(build.buildAll)
async.apply(build.buildAll),
], function (err, data) {
// Disregard build step data
data = data[0];
var separator = ' ';
if (process.stdout.columns > 10) {
for(var x = 0,cols = process.stdout.columns - 10; x < cols; x++) {
for (var x = 0, cols = process.stdout.columns - 10; x < cols; x += 1) {
separator += '=';
}
}
@@ -194,7 +193,7 @@ function upgrade() {
async.apply(db.init),
async.apply(meta.configs.init),
async.apply(upgrade.upgrade),
async.apply(build.buildAll)
async.apply(build.buildAll),
], function (err) {
if (err) {
winston.error(err.stack);

View File

@@ -1,8 +1,8 @@
'use strict';
var bcrypt = require('bcryptjs'),
async = require('async');
var bcrypt = require('bcryptjs');
var async = require('async');
process.on('message', function (msg) {
@@ -20,15 +20,15 @@ function hashPassword(password, rounds) {
},
function (salt, next) {
bcrypt.hash(password, salt, next);
}
},
], done);
}
function done(err, result) {
if (err) {
process.send({err: err.message});
process.send({ err: err.message });
return process.disconnect();
}
process.send({result: result});
process.send({ result: result });
process.disconnect();
}
}

View File

@@ -1,4 +1,4 @@
"use strict";
'use strict';
var async = require('async');
var prompt = require('prompt');
@@ -6,7 +6,7 @@ var winston = require('winston');
var questions = {
redis: require('../src/database/redis').questions,
mongo: require('../src/database/mongo').questions
mongo: require('../src/database/mongo').questions,
};
module.exports = function (config, callback) {
@@ -18,7 +18,7 @@ module.exports = function (config, callback) {
},
function (databaseConfig, next) {
saveDatabaseConfig(config, databaseConfig, next);
}
},
], callback);
};
@@ -55,7 +55,7 @@ function saveDatabaseConfig(config, databaseConfig, callback) {
host: databaseConfig['redis:host'],
port: databaseConfig['redis:port'],
password: databaseConfig['redis:password'],
database: databaseConfig['redis:database']
database: databaseConfig['redis:database'],
};
if (config.redis.host.slice(0, 1) === '/') {
@@ -67,16 +67,16 @@ function saveDatabaseConfig(config, databaseConfig, callback) {
port: databaseConfig['mongo:port'],
username: databaseConfig['mongo:username'],
password: databaseConfig['mongo:password'],
database: databaseConfig['mongo:database']
database: databaseConfig['mongo:database'],
};
} else {
return callback(new Error('unknown database : ' + config.database));
}
var allQuestions = questions.redis.concat(questions.mongo);
for (var x = 0; x < allQuestions.length; x++) {
for (var x = 0; x < allQuestions.length; x += 1) {
delete config[allQuestions[x].name];
}
callback(null, config);
}
}

View File

@@ -1,4 +1,4 @@
"use strict";
'use strict';
var winston = require('winston');
var express = require('express');
@@ -17,9 +17,9 @@ winston.add(winston.transports.File, {
colorize: true,
timestamp: function () {
var date = new Date();
return date.getDate() + '/' + (date.getMonth() + 1) + ' ' + date.toTimeString().substr(0,5) + ' [' + global.process.pid + ']';
return date.getDate() + '/' + (date.getMonth() + 1) + ' ' + date.toTimeString().substr(0, 5) + ' [' + global.process.pid + ']';
},
level: 'verbose'
level: 'verbose',
});
var web = {};
@@ -27,7 +27,7 @@ var scripts = [
'public/vendor/xregexp/xregexp.js',
'public/vendor/xregexp/unicode/unicode-base.js',
'public/src/utils.js',
'public/src/installer/install.js'
'public/src/installer/install.js',
];
web.install = function (port) {
@@ -39,7 +39,7 @@ web.install = function (port) {
app.set('view engine', 'tpl');
app.set('views', path.join(__dirname, '../src/views'));
app.use(bodyParser.urlencoded({
extended: true
extended: true,
}));
async.parallel([compileLess, compileJS], function () {
@@ -66,7 +66,7 @@ function welcome(req, res) {
var databases = dbs.map(function (el) {
return {
name: el,
questions: require('../src/database/' + el).questions
questions: require('../src/database/' + el).questions,
};
});
@@ -75,10 +75,10 @@ function welcome(req, res) {
res.render('install/index', {
databases: databases,
skipDatabaseSetup: !!nconf.get('database'),
error: res.locals.error ? true : false,
success: res.locals.success ? true : false,
error: !!res.locals.error,
success: !!res.locals.success,
values: req.body,
minimumPasswordLength: defaults.minimumPasswordLength
minimumPasswordLength: defaults.minimumPasswordLength,
});
}
@@ -90,7 +90,7 @@ function install(req, res) {
}
var child = require('child_process').fork('app', ['--setup'], {
env: process.env
env: process.env,
});
child.on('close', function (data) {
@@ -110,7 +110,7 @@ function launch(req, res) {
var child = require('child_process').spawn('node', ['loader.js'], {
detached: true,
stdio: ['ignore', 'ignore', 'ignore']
stdio: ['ignore', 'ignore', 'ignore'],
});
process.stdout.write('\nStarting NodeBB\n');
@@ -120,7 +120,7 @@ function launch(req, res) {
async.parallel([
async.apply(fs.unlink(path.join(__dirname, '../public/installer.css'))),
async.apply(fs.unlink(path.join(__dirname, '../public/installer.min.js')))
async.apply(fs.unlink(path.join(__dirname, '../public/installer.min.js'))),
], function (err) {
if (err) {
winston.warn('Unable to remove installer files');
@@ -138,7 +138,7 @@ function compileLess(callback) {
}
less.render(style.toString(), function (err, css) {
if(err) {
if (err) {
return winston.error('Unable to compile LESS: ', err);
}
@@ -157,4 +157,4 @@ function compileJS(callback) {
fs.writeFile(path.join(__dirname, '../public/installer.min.js'), result.code, callback);
}
module.exports = web;
module.exports = web;

View File

@@ -1,29 +1,28 @@
'use strict';
var nconf = require('nconf'),
fs = require('fs'),
url = require('url'),
path = require('path'),
fork = require('child_process').fork,
async = require('async'),
logrotate = require('logrotate-stream'),
file = require('./src/file'),
pkg = require('./package.json');
var nconf = require('nconf');
var fs = require('fs');
var url = require('url');
var path = require('path');
var fork = require('child_process').fork;
var async = require('async');
var logrotate = require('logrotate-stream');
var file = require('./src/file');
var pkg = require('./package.json');
nconf.argv().env().file({
file: path.join(__dirname, '/config.json')
file: path.join(__dirname, 'config.json'),
});
var pidFilePath = __dirname + '/pidfile',
output = logrotate({ file: __dirname + '/logs/output.log', size: '1m', keep: 3, compress: true }),
silent = nconf.get('silent') === 'false' ? false : nconf.get('silent') !== false,
numProcs,
workers = [],
Loader = {
timesStarted: 0
};
var pidFilePath = path.join(__dirname, 'pidfile');
var outputLogFilePath = path.join(__dirname, 'logs/output.log');
var output = logrotate({ file: outputLogFilePath, size: '1m', keep: 3, compress: true });
var silent = nconf.get('silent') === 'false' ? false : nconf.get('silent') !== false;
var numProcs;
var workers = [];
var Loader = {
timesStarted: 0,
};
Loader.init = function (callback) {
if (silent) {
@@ -50,11 +49,10 @@ Loader.displayStartupMessages = function (callback) {
};
Loader.addWorkerEvents = function (worker) {
worker.on('exit', function (code, signal) {
if (code !== 0) {
if (Loader.timesStarted < numProcs * 3) {
Loader.timesStarted++;
Loader.timesStarted += 1;
if (Loader.crashTimer) {
clearTimeout(Loader.crashTimer);
}
@@ -62,7 +60,7 @@ Loader.addWorkerEvents = function (worker) {
Loader.timesStarted = 0;
}, 10000);
} else {
console.log(numProcs * 3 + ' restarts in 10 seconds, most likely an error on startup. Halting.');
console.log((numProcs * 3) + ' restarts in 10 seconds, most likely an error on startup. Halting.');
process.exit();
}
}
@@ -78,13 +76,13 @@ Loader.addWorkerEvents = function (worker) {
worker.on('message', function (message) {
if (message && typeof message === 'object' && message.action) {
switch (message.action) {
case 'restart':
console.log('[cluster] Restarting...');
Loader.restart();
case 'restart':
console.log('[cluster] Restarting...');
Loader.restart();
break;
case 'reload':
console.log('[cluster] Reloading...');
Loader.reload();
case 'reload':
console.log('[cluster] Reloading...');
Loader.reload();
break;
}
}
@@ -95,7 +93,7 @@ Loader.start = function (callback) {
numProcs = getPorts().length;
console.log('Clustering enabled: Spinning up ' + numProcs + ' process(es).\n');
for (var x = 0; x < numProcs; ++x) {
for (var x = 0; x < numProcs; x += 1) {
forkWorker(x, x === 0);
}
@@ -108,17 +106,17 @@ function forkWorker(index, isPrimary) {
var ports = getPorts();
var args = [];
if(!ports[index]) {
if (!ports[index]) {
return console.log('[cluster] invalid port for worker : ' + index + ' ports: ' + ports.length);
}
process.env.isPrimary = isPrimary;
process.env.isCluster = ports.length > 1 ? true : false;
process.env.isCluster = ports.length > 1;
process.env.port = ports[index];
var worker = fork('app.js', args, {
silent: silent,
env: process.env
env: process.env,
});
worker.index = index;
@@ -129,7 +127,7 @@ function forkWorker(index, isPrimary) {
Loader.addWorkerEvents(worker);
if (silent) {
var output = logrotate({ file: __dirname + '/logs/output.log', size: '1m', keep: 3, compress: true });
var output = logrotate({ file: outputLogFilePath, size: '1m', keep: 3, compress: true });
worker.stdout.pipe(output);
worker.stderr.pipe(output);
}
@@ -156,7 +154,7 @@ Loader.restart = function () {
nconf.remove('file');
nconf.use('file', { file: pathToConfig });
fs.readFile(pathToConfig, {encoding: 'utf-8'}, function (err, configFile) {
fs.readFile(pathToConfig, { encoding: 'utf-8' }, function (err, configFile) {
if (err) {
console.log('Error reading config : ' + err.message);
process.exit();
@@ -175,7 +173,7 @@ Loader.restart = function () {
Loader.reload = function () {
workers.forEach(function (worker) {
worker.send({
action: 'reload'
action: 'reload',
});
});
};
@@ -184,7 +182,7 @@ Loader.stop = function () {
killWorkers();
// Clean up the pidfile
fs.unlinkSync(__dirname + '/pidfile');
fs.unlinkSync(pidFilePath);
};
function killWorkers() {
@@ -222,16 +220,16 @@ fs.open(path.join(__dirname, 'config.json'), 'r', function (err) {
require('daemon')({
stdout: process.stdout,
stderr: process.stderr
stderr: process.stderr,
});
fs.writeFile(__dirname + '/pidfile', process.pid);
fs.writeFileSync(pidFilePath, process.pid);
}
async.series([
Loader.init,
Loader.displayStartupMessages,
Loader.start
Loader.start,
], function (err) {
if (err) {
console.log('[loader] Error during startup: ' + err.message);
@@ -239,6 +237,6 @@ fs.open(path.join(__dirname, 'config.json'), 'r', function (err) {
});
} else {
// No config detected, kickstart web installer
var child = require('child_process').fork('app');
require('child_process').fork('app');
}
});

View File

@@ -52,17 +52,17 @@
"morgan": "^1.3.2",
"mousetrap": "^1.5.3",
"nconf": "~0.8.2",
"nodebb-plugin-composer-default": "4.4.1",
"nodebb-plugin-composer-default": "4.4.2",
"nodebb-plugin-dbsearch": "1.0.5",
"nodebb-plugin-emoji-extended": "1.1.1",
"nodebb-plugin-emoji-one": "1.1.5",
"nodebb-plugin-markdown": "7.1.1",
"nodebb-plugin-mentions": "1.1.3",
"nodebb-plugin-soundpack-default": "1.0.0",
"nodebb-plugin-spam-be-gone": "0.4.10",
"nodebb-plugin-spam-be-gone": "0.4.13",
"nodebb-rewards-essentials": "0.0.9",
"nodebb-theme-lavender": "3.0.15",
"nodebb-theme-persona": "4.2.4",
"nodebb-theme-lavender": "4.0.0",
"nodebb-theme-persona": "4.2.6",
"nodebb-theme-vanilla": "5.2.0",
"nodebb-widget-essentials": "2.0.13",
"nodemailer": "2.6.4",
@@ -87,22 +87,21 @@
"socket.io-redis": "3.1.0",
"socketio-wildcard": "~0.3.0",
"string": "^3.0.0",
"templates.js": "0.3.6",
"templates.js": "0.3.10",
"toobusy-js": "^0.5.1",
"uglify-js": "^2.6.0",
"underscore": "^1.8.3",
"underscore.deep": "^0.5.1",
"validator": "^6.1.0",
"winston": "^2.1.0",
"xml": "^1.0.1",
"xregexp": "~3.1.0"
},
"devDependencies": {
"coveralls": "^2.11.14",
"eslint": "^3.12.0",
"eslint-config-airbnb": "^13.0.0",
"eslint-plugin-import": "^2.0.0",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.8.0",
"eslint-config-airbnb-base": "^11.1.0",
"eslint-plugin-import": "^2.2.0",
"grunt": "~1.0.0",
"grunt-contrib-watch": "^1.0.0",
"istanbul": "^0.4.2",

58
public/.eslintrc Normal file
View File

@@ -0,0 +1,58 @@
{
"globals": {
"app": true,
"io": true,
"socket": true,
"ajaxify": true,
"config": true,
"RELATIVE_PATH": true,
"utils": true,
"overrides": true,
"componentHandler": true,
"bootbox": true,
"templates": true,
"Visibility": true,
"Tinycon": true,
"Promise": true
},
"env": {
"jquery": true,
"amd": true,
"browser": true,
"es6": false
},
"rules": {
"no-dupe-class-members": "off",
"no-var": "off",
"object-shorthand": "off",
"prefer-arrow-callback": "off",
"prefer-spread": "off",
"prefer-reflect": "off",
"prefer-template": "off"
},
"parserOptions": {
"ecmaVersion": 5,
"ecmaFeatures": {
"arrowFunctions": false,
"classes": false,
"defaultParams": false,
"destructuring": false,
"experimentalObjectRestSpread": false,
"blockBindings": false,
"forOf": false,
"generators": false,
"globalReturn": false,
"jsx": false,
"modules": false,
"objectLiteralComputedProperties": false,
"objectLiteralDuplicateProperties": false,
"objectLiteralShorthandMethods": false,
"objectLiteralShorthandProperties": false,
"impliedStrict": false,
"restParams": false,
"spread": false,
"superInFunctions": false,
"templateStrings": false
}
}
}

84
public/.jshintrc Normal file
View File

@@ -0,0 +1,84 @@
{
"maxerr" : 50, // {int} Maximum error before stopping
// Enforcing
"bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.)
"camelcase" : false, // true: Identifiers must be in camelCase
"curly" : true, // true: Require {} for every new block or scope
"eqeqeq" : true, // true: Require triple equals (===) for comparison
"forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty()
"immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
"indent" : 4, // {int} Number of spaces to use for indentation
"latedef" : false, // true: Require variables/functions to be defined before being used
"newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()`
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
"noempty" : true, // true: Prohibit use of empty blocks
"nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
"plusplus" : false, // true: Prohibit use of `++` & `--`
"quotmark" : false, // Quotation mark consistency:
// false : do nothing (default)
// true : ensure whatever is used is consistent
// "single" : require single quotes
// "double" : require double quotes
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
"unused" : true, // true: Require all defined variables be used
"strict" : true, // true: Requires all functions run in ES5 Strict Mode
"trailing" : false, // true: Prohibit trailing whitespaces
"maxparams" : false, // {int} Max number of formal params allowed per function
"maxdepth" : false, // {int} Max depth of nested blocks (within functions)
"maxstatements" : false, // {int} Max number statements per function
"maxcomplexity" : false, // {int} Max cyclomatic complexity per function
"maxlen" : false, // {int} Max number of characters per line
// Relaxing
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"boss" : false, // true: Tolerate assignments where comparisons would be expected
"debug" : false, // true: Allow debugger statements e.g. browser breakpoints.
"eqnull" : false, // true: Tolerate use of `== null`
"es5" : false, // true: Allow ES5 syntax (ex: getters and setters)
"esnext" : false, // true: Allow ES.next (ES6) syntax (ex: `const`)
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
// (ex: `for each`, multiple try/catch, function expression…)
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
"expr" : false, // true: Tolerate `ExpressionStatement` as Programs
"funcscope" : false, // true: Tolerate defining variables inside control statements"
"globalstrict" : false, // true: Allow global "use strict" (also enables 'strict')
"iterator" : false, // true: Tolerate using the `__iterator__` property
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
"laxbreak" : false, // true: Tolerate possibly unsafe line breakings
"laxcomma" : false, // true: Tolerate comma-first style coding
"loopfunc" : false, // true: Tolerate functions being defined in loops
"multistr" : false, // true: Tolerate multi-line strings
"proto" : false, // true: Tolerate using the `__proto__` property
"scripturl" : false, // true: Tolerate script-targeted URLs
"smarttabs" : false, // true: Tolerate mixed tabs/spaces when used for alignment
"shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
"validthis" : false, // true: Tolerate using this in a non-constructor function
"globals": {
"app": true,
"io": true,
"socket": true,
"ajaxify": true,
"config": true,
"RELATIVE_PATH": true,
"utils": true,
"overrides": true,
"componentHandler": true,
"bootbox": true,
"templates": true,
"Visibility": true,
"Tinycon": true,
"require": true,
"define": true,
"ace": true,
"Sortable": true,
"Slideout": true,
"NProgress": true
},
"jquery": true,
"browser": true
}

View File

@@ -1,6 +1,6 @@
{
"events": "Veranstaltungen",
"no-events": "Es gibt keine Veranstaltungen",
"control-panel": "Veranstaltungen Steuerung",
"delete-events": "Veranstaltungen löschen"
"events": "Ereignisse",
"no-events": "Es gibt keine Ereignisse",
"control-panel": "Ereignis-Steuerung",
"delete-events": "Ereignisse löschen"
}

View File

@@ -9,7 +9,7 @@
"search": "Search",
"dismiss-all": "Dismiss All",
"none-flagged": "No flagged posts!",
"posted-in": "Posted in %1",
"posted-in": "Posted in",
"read-more": "Read More",
"flagged-x-times": "This post has been flagged %1 time(s):",
"dismiss": "Dismiss this Flag",

View File

@@ -26,5 +26,6 @@
"touch-icon.upload": "Upload",
"touch-icon.help": "Recommended size and format: 192x192, PNG format only. If no touch icon is specified, NodeBB will fall back to using the favicon.",
"outgoing-links": "Outgoing Links",
"outgoing-links.warning-page": "Use Outgoing Links Warning Page"
"outgoing-links.warning-page": "Use Outgoing Links Warning Page",
"outgoing-links.whitelist": "Domains to whitelist for bypassing the warning page"
}

View File

@@ -32,6 +32,7 @@
"details.disableJoinRequests": "Disable join requests",
"details.grant": "Grant/Rescind Ownership",
"details.kick": "Kick",
"details.kick_confirm": "Are you sure you want to remove this member from the group?",
"details.owner_options": "Group Administration",
"details.group_name": "Group Name",

View File

@@ -8,27 +8,27 @@
"mongo.version": "Versione MongoDB",
"mongo.storage-engine": "Storage Engine",
"mongo.collections": "Collections",
"mongo.objects": "Objects",
"mongo.avg-object-size": "Avg. Object Size",
"mongo.data-size": "Data Size",
"mongo.storage-size": "Storage Size",
"mongo.index-size": "Index Size",
"mongo.file-size": "File Size",
"mongo.resident-memory": "Resident Memory",
"mongo.virtual-memory": "Virtual Memory",
"mongo.mapped-memory": "Mapped Memory",
"mongo.objects": "Oggetti",
"mongo.avg-object-size": "Dimensione Media dell'Oggetto",
"mongo.data-size": "Dimensione del Data",
"mongo.storage-size": "Dimensione dello Spazio di Archiviazione",
"mongo.index-size": "Dimensione dell'Indice",
"mongo.file-size": "Dimensione del file",
"mongo.resident-memory": "Memoria Allocata",
"mongo.virtual-memory": "Memoria Virtuale",
"mongo.mapped-memory": "Memoria Mappata",
"mongo.raw-info": "MongoDB Raw Info",
"redis": "Redis",
"redis.version": "Redis Version",
"redis.connected-clients": "Connected Clients",
"redis.version": "Versione Redis",
"redis.connected-clients": "Clients Connessi",
"redis.connected-slaves": "Connected Slaves",
"redis.blocked-clients": "Blocked Clients",
"redis.used-memory": "Used Memory",
"redis.memory-frag-ratio": "Memory Fragmentation Ratio",
"redis.total-connections-recieved": "Total Connections Received",
"redis.total-commands-processed": "Total Commands Processed",
"redis.iops": "Instantaneous Ops. Per Second",
"redis.blocked-clients": "Clients Bloccati",
"redis.used-memory": "Memoria Usata",
"redis.memory-frag-ratio": "Rateo della Frammentazione della Memoria",
"redis.total-connections-recieved": "Totale Connessioni Ricevute",
"redis.total-commands-processed": "Totale Comandi Processati",
"redis.iops": "Operazioni Instantanee al Secondo",
"redis.keyspace-hits": "Keyspace Hits",
"redis.keyspace-misses": "Keyspace Misses",
"redis.raw-info": "Redis Raw Info"

View File

@@ -1,14 +1,14 @@
{
"figure-x": "Figure %1",
"error-events-per-day": "<code>%1</code> events per day",
"error.404": "404 Not Found",
"error.503": "503 Service Unavailable",
"manage-error-log": "Manage Error Log",
"export-error-log": "Export Error Log (CSV)",
"clear-error-log": "Clear Error Log",
"route": "Route",
"count": "Count",
"no-routes-not-found": "Hooray! No 404 errors!",
"clear404-confirm": "Are you sure you wish to clear the 404 error logs?",
"clear404-success": "\"404 Not Found\" errors cleared"
"figure-x": "Figura %1",
"error-events-per-day": "<code>%1</code> eventi per giorno",
"error.404": "404 Non Trovato",
"error.503": "503 Servizio Non Disponibile",
"manage-error-log": "Gestisci il Registro degli Errori",
"export-error-log": "Esporta il Registro degli Errori (CSV)",
"clear-error-log": "Cancella il Registro degli Errori",
"route": "Strada",
"count": "Numero",
"no-routes-not-found": "Hooray! Nessun Errore 404!",
"clear404-confirm": "Sei sicuro di voler cancellare il Registro degli Errori 404?",
"clear404-success": "Error \"404 Non Trovato\" Cancellati"
}

View File

@@ -1,6 +1,6 @@
{
"events": "Events",
"no-events": "There are no events",
"control-panel": "Events Control Panel",
"delete-events": "Delete Events"
"events": "Eventi",
"no-events": "Non ci sono Eventi",
"control-panel": "Pannello di controllo degli Eventi",
"delete-events": "Cancella gli Eventi"
}

View File

@@ -1,7 +1,7 @@
{
"logs": "Logs",
"control-panel": "Logs Control Panel",
"reload": "Reload Logs",
"clear": "Clear Logs",
"clear-success": "Logs Cleared!"
"logs": "Registri",
"control-panel": "Pannello di Controllo dei Registri",
"reload": "Ricarica i Registri",
"clear": "Cancella i Registri",
"clear-success": "Registri Cancellati!"
}

View File

@@ -1,9 +1,9 @@
{
"custom-css": "Custom CSS",
"custom-css.description": "Enter your own CSS declarations here, which will be applied after all other styles.",
"custom-css.enable": "Enable Custom CSS",
"custom-css": "CSS Personalizzato",
"custom-css.description": "Inserisci le tue dichiarazioni CSS qui, verranno applicate dopo tutti gli altri stili.",
"custom-css.enable": "Abilita CSS Personalizzato",
"custom-header": "Custom Header",
"custom-header.description": "Enter custom HTML here (ex. JavaScript, Meta Tags, etc.), which will be appended to the <code>&lt;head&gt;</code> section of your forum's markup.",
"custom-header.enable": "Enable Custom Header"
"custom-header": "Intestazione Personalizzata",
"custom-header.description": "Inserisci l' HTML personalizzato qui (es. JavaScript, Meta Tags, ecc.), verrà attaccato al codice <code>&lt;head&gt;</code> sezione del markup del tuo forum",
"custom-header.enable": "Abilita l'Intestazione Personalizzata"
}

View File

@@ -1,9 +1,9 @@
{
"loading": "Loading Skins...",
"homepage": "Homepage",
"select-skin": "Select Skin",
"current-skin": "Current Skin",
"skin-updated": "Skin Updated",
"applied-success": "%1 skin was succesfully applied",
"revert-success": "Skin reverted to base colours"
"loading": "Caricamento Skins",
"homepage": "Pagina Home",
"select-skin": "Seleziona la Skin",
"current-skin": "Skin Corrente",
"skin-updated": "Skin Aggiornata",
"applied-success": "%1 skin è stata applicata con successo",
"revert-success": "Skin riportata ai colori base"
}

View File

@@ -1,11 +1,11 @@
{
"checking-for-installed": "Checking for installed themes...",
"homepage": "Homepage",
"select-theme": "Select Theme",
"current-theme": "Current Theme",
"no-themes": "No installed themes found",
"revert-confirm": "Are you sure you wish to restore the default NodeBB theme?",
"theme-changed": "Theme Changed",
"revert-success": "You have successfully reverted your NodeBB back to it's default theme.",
"restart-to-activate": "Please restart your NodeBB to fully activate this theme"
"checking-for-installed": "Controllando se ci sono temi installati...",
"homepage": "Pagina Home",
"select-theme": "Seleziona il Tema",
"current-theme": "Tema Corrente",
"no-themes": "Nessun tema installato trovato",
"revert-confirm": "Sei sicuro di voler ripristinare al tema originale di NodeBB?",
"theme-changed": "Tema Cambiato",
"revert-success": "Hai correttamente ripristinato il tuo NodeBB al tema originale.",
"restart-to-activate": "Perfavore riavvia il tuo NodeBB per attivare correttamente questo tema"
}

View File

@@ -1,16 +1,16 @@
{
"you-are-on": "Info - You are on <strong>%1:%2</strong>",
"you-are-on": "Informazione - Tu sei su <strong>%1:%2</strong>",
"host": "host",
"pid": "pid",
"nodejs": "nodejs",
"online": "online",
"git": "git",
"load": "load",
"uptime": "uptime",
"load": "carica",
"uptime": "tempo di caricamento",
"registered": "Registered",
"registered": "Registrato",
"sockets": "Sockets",
"guests": "Guests",
"guests": "Ospiti",
"info": "Info"
"info": "Informazioni"
}

View File

@@ -1,6 +1,6 @@
{
"logger-settings": "Logger Settings",
"description": "By enabling the check boxes, you will receive logs to your terminal. If you specify a path, logs will then be saved to a file instead. HTTP logging is useful for collecting statistics about who, when, and what people access on your forum. In addition to logging HTTP requests, we can also log socket.io events. Socket.io logging, in combination with redis-cli monitor, can be very helpful for learning NodeBB's internals.",
"logger-settings": "Impostazioni del Registratore",
"description": "Abilitando le \"check boxes\", riceverai i registri sul tuo terminale. Se vuoi specificare un percorso, i registri verranno invece salvati in un file. Registrare l' HTTP è utile per collezionare statistiche su chi, quando, e a cosa le persone hanno accesso sul tuo forum. In più sul registrare le richieste HTTP, in combinazione con il monitoraggio redis-cli, può essere veramente utile per imparare l'interno di NodeBB",
"explanation": "Simply check/uncheck the logging settings to enable or disable logging on the fly. No restart needed.",
"enable-http": "Enable HTTP logging",
"enable-socket": "Enable socket.io event logging",

View File

@@ -1,5 +1,5 @@
{
"general": "General",
"general": "Ogólne",
"private-groups": "Prywatne Grupy",
"private-groups.help": "If enabled, joining of groups requires the approval of the group owner <em>(Default: enabled)</em>",
"private-groups.warning": "<strong>Beware!</strong> If this option is disabled and you have private groups, they automatically become public.",

View File

@@ -1,6 +1,6 @@
{
"tag": "Ustawienia Tagów",
"min-per-topic": "Minimum Tags per Topic",
"min-per-topic": "Minimalna ilość Tagów na Temat",
"max-per-topic": "Maximum Tags per Topic",
"min-length": "Minimum Tag Length",
"max-length": "Maximum Tag Length",

View File

@@ -1,6 +1,6 @@
{
"posts": "Posty",
"allow-files": "Allow users to upload regular files",
"allow-files": "Pozwolić użytkownikom wgrywać pliki",
"private": "Make uploaded files private",
"max-image-width": "Resize images down to specified width (in pixels)",
"max-image-width-help": "(in pixels, default: 760 pixels, set to 0 to disable)",

View File

@@ -15,7 +15,7 @@
"invalid-username-or-password": "Молимо наведите и корисничко име и лозинку",
"invalid-search-term": "Неисправан упит за претрагу",
"csrf-invalid": "Нисмо успели да вас пријавимо, вероватно због истека сесије. Молимо покушајте поново",
"invalid-pagination-value": "Неважећа вредност при обележавању страна, мора бити најмање %1 а највише %2 ",
"invalid-pagination-value": "Неважећа вредност приликом нумерисања страница, мора бити најмање %1 а највише %2 ",
"username-taken": "Корисничко име је заузето",
"email-taken": "Адреса е-поште је заузета",
"email-not-confirmed": "Ваша адреса е-поште још увек није оверена, кликните овде да би сте то учинили.",

View File

@@ -21,7 +21,7 @@
"save_changes": "Сачувај измене",
"save": "Сачувај",
"close": "Затвори",
"pagination": "Обележавање страна",
"pagination": "Нумерисање страница",
"pagination.out_of": "%1 од %2",
"pagination.enter_index": "Унесите индекс",
"header.admin": "Админ",

View File

@@ -13,7 +13,7 @@
"notify_me": "Будите обавештени о новим порукама у овој теми",
"quote": "Цитирај",
"reply": "Одговори",
"replies_to_this_post": "%1 одговора",
"replies_to_this_post": "Одговора: %1",
"last_reply_time": "Последњи одговор",
"reply-as-topic": "Постави одговор као тему",
"guest-login-reply": "Пријавите се да бисте одговорили",

View File

@@ -31,7 +31,7 @@
"signature": "Потпис",
"birthday": "Рођендан",
"chat": "Ђаскање",
"chat_with": "Настави ћаскање са %1",
"chat_with": "Ћаскај са %1",
"new_chat_with": "Започни ново ћаскање са %1",
"flag-profile": "Означи профил",
"follow": "Прати",
@@ -90,7 +90,7 @@
"has_no_voted_posts": "Овај корисник нема објаве за које се гласало.",
"email_hidden": "Скривена е-пошта",
"hidden": "скривена",
"paginate_description": "Подели теме и поруке по страницама уместо бесконачног скроловања",
"paginate_description": "Нумериши теме и странице уместо бесконачног скроловања",
"topics_per_page": "Тема по страници",
"posts_per_page": "Порука по страници",
"notification_sounds": "Репродукуј звук приликом примања обавештења",

View File

@@ -1,9 +1,9 @@
{
"chat-settings": "Sohbet Ayarları",
"disable": "Sohbeti kapat",
"disable-editing": "Disable chat message editing/deletion",
"disable-editing": "Sohbet mesajlarını düzenlemeyi/silmeyi kapat",
"disable-editing-help": "Administrators and global moderators are exempt from this restriction",
"max-length": "Maximum length of chat messages",
"max-length": "Maksimum sohbet mesajı uzunluğu",
"max-room-size": "Maximum number of users in chat rooms",
"delay": "Time between chat messages in milliseconds"
}

View File

@@ -7,14 +7,14 @@
"allow-login-with": "Allow login with",
"allow-login-with.username-email": "Kullanıcı adı veya Email",
"allow-login-with.username": "Sadece kullanıcı adı",
"allow-login-with.email": "Email Only",
"allow-login-with.email": "Sadece Email",
"account-settings": "Hesap Ayarları",
"disable-username-changes": "Disable username changes",
"disable-email-changes": "Disable email changes",
"disable-password-changes": "Disable password changes",
"allow-account-deletion": "Allow account deletion",
"user-info-private": "Make user info private",
"themes": "Themes",
"disable-username-changes": "Kullanıcı adı değişikliği kapalı",
"disable-email-changes": "Email değişikliği kapalı",
"disable-password-changes": "Parola değişikliği kapalı",
"allow-account-deletion": "Hesap silmeye izin ver",
"user-info-private": "Kullanıcı bilgilerini gizli yap",
"themes": "Temalar",
"disable-user-skins": "Prevent users from choosing a custom skin",
"account-protection": "Account Protection",
"login-attempts": "Login attempts per hour",
@@ -23,13 +23,13 @@
"login-days": "Days to remember user login sessions",
"password-expiry-days": "Force password reset after a set number of days",
"registration": "User Registration",
"registration-type": "Registration Type",
"registration-type": "Kayıt Tipi",
"registration-type.normal": "Normal",
"registration-type.admin-approval": "Admin Approval",
"registration-type.admin-approval-ip": "Admin Approval for IPs",
"registration-type.invite-only": "Invite Only",
"registration-type.admin-invite-only": "Admin Invite Only",
"registration-type.disabled": "No registration",
"registration-type.admin-approval": "Yönetici Onayı",
"registration-type.admin-approval-ip": "IP'ler için Yönetici Onayı",
"registration-type.invite-only": "Sadece Davet",
"registration-type.admin-invite-only": "Sadece Yönetici Daveti",
"registration-type.disabled": "Kayıt yok",
"registration-type.help": "Normal - Users can register from the /register page.<br/>\nAdmin Approval - User registrations are placed in an <a href=\"%1/admin/manage/registration\">approval queue</a> for administrators.<br/>\nAdmin Approval for IPs - Normal for new users, Admin Approval for IP addresses that already have an account.<br/>\nInvite Only - Users can invite others from the <a href=\"%1/users\" target=\"_blank\">users</a> page.<br/>\nAdmin Invite Only - Only administrators can invite others from <a href=\"%1/users\" target=\"_blank\">users</a> and <a href=\"%1/admin/manage/users\">admin/manage/users</a> pages.<br/>\nNo registration - No user registration.<br/>",
"registration.max-invites": "Maximum Invitations per User",
"max-invites": "Maximum Invitations per User",

View File

@@ -1,7 +1,7 @@
{
"alert.confirm-reload": "Are you sure you wish to reload NodeBB?",
"alert.confirm-restart": "Are you sure you wish to restart NodeBB?",
"alert.confirm-reload": "Bạn có thật sự muốn tải lại NodeBB",
"alert.confirm-restart": "Bạn có thật sự muốn khởi động lại NodeBB",
"acp-title": "%1 | NodeBB Admin Control Panel",
"settings-header-contents": "Contents"
"acp-title": "%1 | Bảng điểu khiển",
"settings-header-contents": "Nội dung"
}

View File

@@ -1,11 +1,11 @@
{
"post-cache": "Post Cache",
"posts-in-cache": "Posts in Cache",
"average-post-size": "Average Post Size",
"length-to-max": "Length / Max",
"percent-full": "%1% Full",
"post-cache-size": "Post Cache Size",
"items-in-cache": "Items in Cache",
"control-panel": "Control Panel",
"update-settings": "Update Cache Settings"
"post-cache": "Cache bài viết",
"posts-in-cache": "Cache cho bài viết",
"average-post-size": "Kích thước bài viết",
"length-to-max": "Độ dài / Tối Đa",
"percent-full": "%1% Đầy",
"post-cache-size": "Kích thước cache bài viết",
"items-in-cache": "Thành phần trong Cache",
"control-panel": "Bảng điều khiển",
"update-settings": "Cập nhật thiết lập Cache"
}

View File

@@ -1,30 +1,30 @@
{
"x-b": "%1 b",
"x-mb": "%1 mb",
"uptime-seconds": "Uptime in Seconds",
"uptime-days": "Uptime in Days",
"uptime-seconds": "Thời gian hoạt động(giây)",
"uptime-days": "Thời gian hoạt động(Ngày)",
"mongo": "Mongo",
"mongo.version": "MongoDB Version",
"mongo.storage-engine": "Storage Engine",
"mongo.collections": "Collections",
"mongo.objects": "Objects",
"mongo.avg-object-size": "Avg. Object Size",
"mongo.data-size": "Data Size",
"mongo.storage-size": "Storage Size",
"mongo.index-size": "Index Size",
"mongo.file-size": "File Size",
"mongo.version": "Phiên bản MongoDB ",
"mongo.storage-engine": "Lưu Trữ",
"mongo.collections": "Tập dữ liệu",
"mongo.objects": "Đối tượng",
"mongo.avg-object-size": "Kích thước trung bình",
"mongo.data-size": "Kích thước dữ liệu",
"mongo.storage-size": "Kích thước lưu trữ",
"mongo.index-size": "Kích thước chỉ mục",
"mongo.file-size": "Kích thước tập tin",
"mongo.resident-memory": "Resident Memory",
"mongo.virtual-memory": "Virtual Memory",
"mongo.virtual-memory": "Bộ nhớ ảo",
"mongo.mapped-memory": "Mapped Memory",
"mongo.raw-info": "MongoDB Raw Info",
"mongo.raw-info": "Thông tin MongoDB",
"redis": "Redis",
"redis.version": "Redis Version",
"redis.connected-clients": "Connected Clients",
"redis.version": "Phiên bản Redis",
"redis.connected-clients": "Người dùng kết nối",
"redis.connected-slaves": "Connected Slaves",
"redis.blocked-clients": "Blocked Clients",
"redis.used-memory": "Used Memory",
"redis.blocked-clients": "Người dùng vi phạm",
"redis.used-memory": "Bộ nhớ đã sử dụng",
"redis.memory-frag-ratio": "Memory Fragmentation Ratio",
"redis.total-connections-recieved": "Total Connections Received",
"redis.total-commands-processed": "Total Commands Processed",

View File

@@ -103,5 +103,5 @@
"cookies.message": "Trang web này sử dụng cookie để đảm bảo trải nghiệm tốt nhất cho người dùng",
"cookies.accept": "Đã rõ!",
"cookies.learn_more": "Xem thêm",
"edited": "Edited"
"edited": "Đã cập nhật"
}

View File

@@ -13,8 +13,8 @@
"notify_me": "Được thông báo khi có trả lời mới trong chủ đề này",
"quote": "Trích dẫn",
"reply": "Trả lời",
"replies_to_this_post": "%1 Replies",
"last_reply_time": "Last reply",
"replies_to_this_post": "%1 trả lời",
"last_reply_time": "Trả lời cuối cùng",
"reply-as-topic": "Trả lời dưới dạng chủ đề",
"guest-login-reply": "Hãy đăng nhập để trả lời",
"edit": "Chỉnh sửa",

View File

@@ -2,11 +2,11 @@
"latest_users": "最新会员",
"top_posters": "发帖排行",
"most_reputation": "声望排行",
"most_flags": "被举报次数最多",
"most_flags": "最多举报",
"search": "搜索",
"enter_username": "输入用户名搜索",
"load_more": "加载更多",
"users-found-search-took": "找到 %1 位用户!耗时 %2 秒。",
"users-found-search-took": "找到 %1 位用户!耗时 %2 秒。",
"filter-by": "过滤选项",
"online-only": "只看在线",
"invite": "邀请注册",

View File

@@ -272,4 +272,8 @@ body {
border: 1px dashed @brand-success;
background: lighten(@brand-success, 10%);
opacity: 0.5;
}
form small {
color: @gray-light;
}

View File

@@ -16,4 +16,20 @@
[data-action="upload"][type="text"] {
width: 95%;
}
.bootstrap-tagsinput {
width: 100%;
border: 0;
box-shadow: none;
padding-left: 0;
input {
width: 100%;
margin-left: 1px;
margin-top: 9px;
border-bottom: 1px dotted #ccc !important;
padding-bottom: 5px;
padding-left: 0;
}
}
}

View File

@@ -0,0 +1,8 @@
{
"globals": {
"ace": true,
"Sortable": true,
"Slideout": true,
"NProgress": true
}
}

View File

@@ -1,5 +1,4 @@
"use strict";
/*global config, componentHandler, socket, app, bootbox, Slideout, NProgress, utils*/
'use strict';
(function () {
var logoutTimer = 0;
@@ -14,7 +13,7 @@
message: '[[login:logged-out-due-to-inactivity]]',
callback: function () {
window.location.reload();
}
},
});
}, 3600000);
}
@@ -34,7 +33,7 @@
$(document).ready(function () {
setupKeybindings();
if(!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
if (!/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
require(['admin/modules/search'], function (search) {
search.init();
});
@@ -109,14 +108,15 @@
var mainTitle;
var pageTitle;
if (/admin\/general\/dashboard$/.test(url)) {
mainTitle = pageTitle = '[[admin/menu:general/dashboard]]';
pageTitle = '[[admin/menu:general/dashboard]]';
mainTitle = pageTitle;
} else if (/admin\/plugins\//.test(url)) {
mainTitle = fallback;
pageTitle = '[[admin/menu:section-plugins]] > ' + mainTitle;
} else {
var matches = url.match(/admin\/(.+?)\/(.+?)$/);
mainTitle = '[[admin/menu:' + matches[1] + '/' + matches[2] + ']]';
pageTitle = '[[admin/menu:section-' +
pageTitle = '[[admin/menu:section-' +
(matches[1] === 'development' ? 'advanced' : matches[1]) +
']]' + (matches[2] ? (' > ' + mainTitle) : '');
if (matches[2] === 'settings') {
@@ -158,14 +158,14 @@
}
function launchSnackbar(params) {
var message = (params.title ? "<strong>" + params.title + "</strong>" : '') + (params.message ? params.message : '');
var message = (params.title ? '<strong>' + params.title + '</strong>' : '') + (params.message ? params.message : '');
require(['translator'], function (translator) {
translator.translate(message, function (html) {
var bar = $.snackbar({
content: html,
timeout: params.timeout || 3000,
htmlAllowed: true
htmlAllowed: true,
});
if (params.clickfn) {
@@ -177,18 +177,18 @@
function configureSlidemenu() {
var env = utils.findBootstrapEnvironment();
var slideout = new Slideout({
'panel': document.getElementById('panel'),
'menu': document.getElementById('menu'),
'padding': 256,
'tolerance': 70
panel: document.getElementById('panel'),
menu: document.getElementById('menu'),
padding: 256,
tolerance: 70,
});
if (env === 'md' || env === 'lg') {
slideout.disableTouch();
}
$('#mobile-menu').on('click', function () {
slideout.toggle();
});
@@ -199,36 +199,36 @@
$(window).on('resize', function () {
slideout.close();
env = utils.findBootstrapEnvironment();
if (env === 'md' || env === 'lg') {
slideout.disableTouch();
$('#header').css({
'position': 'relative'
});
position: 'relative',
});
} else {
slideout.enableTouch();
$('#header').css({
'position': 'fixed'
position: 'fixed',
});
}
});
function onOpeningMenu() {
$('#header').css({
'top': $('#panel').position().top * -1 + 'px',
'position': 'absolute'
top: ($('#panel').position().top * -1) + 'px',
position: 'absolute',
});
}
slideout.on('open', onOpeningMenu);
slideout.on('close', function () {
$('#header').css({
'top': '0px',
'position': 'fixed'
top: '0px',
position: 'fixed',
});
});
}
}());
}());

View File

@@ -1,7 +1,7 @@
"use strict";
/*global config, define, app, socket, ajaxify, bootbox, templates, Chart, utils */
'use strict';
define('admin/advanced/errors', ['Chart', 'translator'], function (Chart, translator) {
define('admin/advanced/errors', ['Chart'], function (Chart) {
var Errors = {};
Errors.init = function () {
@@ -26,9 +26,9 @@ define('admin/advanced/errors', ['Chart', 'translator'], function (Chart, transl
};
Errors.setupCharts = function () {
var notFoundCanvas = document.getElementById('not-found'),
tooBusyCanvas = document.getElementById('toobusy'),
dailyLabels = utils.getDaysArray();
var notFoundCanvas = document.getElementById('not-found');
var tooBusyCanvas = document.getElementById('toobusy');
var dailyLabels = utils.getDaysArray();
dailyLabels = dailyLabels.slice(-7);
@@ -41,73 +41,73 @@ define('admin/advanced/errors', ['Chart', 'translator'], function (Chart, transl
labels: dailyLabels,
datasets: [
{
label: "",
backgroundColor: "rgba(186,139,175,0.2)",
borderColor: "rgba(186,139,175,1)",
pointBackgroundColor: "rgba(186,139,175,1)",
pointHoverBackgroundColor: "#fff",
pointBorderColor: "#fff",
pointHoverBorderColor: "rgba(186,139,175,1)",
data: ajaxify.data.analytics['not-found']
}
]
label: '',
backgroundColor: 'rgba(186,139,175,0.2)',
borderColor: 'rgba(186,139,175,1)',
pointBackgroundColor: 'rgba(186,139,175,1)',
pointHoverBackgroundColor: '#fff',
pointBorderColor: '#fff',
pointHoverBorderColor: 'rgba(186,139,175,1)',
data: ajaxify.data.analytics['not-found'],
},
],
},
'toobusy': {
toobusy: {
labels: dailyLabels,
datasets: [
{
label: "",
backgroundColor: "rgba(151,187,205,0.2)",
borderColor: "rgba(151,187,205,1)",
pointBackgroundColor: "rgba(151,187,205,1)",
pointHoverBackgroundColor: "#fff",
pointBorderColor: "#fff",
pointHoverBorderColor: "rgba(151,187,205,1)",
data: ajaxify.data.analytics['toobusy']
}
]
}
label: '',
backgroundColor: 'rgba(151,187,205,0.2)',
borderColor: 'rgba(151,187,205,1)',
pointBackgroundColor: 'rgba(151,187,205,1)',
pointHoverBackgroundColor: '#fff',
pointBorderColor: '#fff',
pointHoverBorderColor: 'rgba(151,187,205,1)',
data: ajaxify.data.analytics.toobusy,
},
],
},
};
notFoundCanvas.width = $(notFoundCanvas).parent().width();
tooBusyCanvas.width = $(tooBusyCanvas).parent().width();
new Chart(notFoundCanvas.getContext('2d'), {
type: 'line',
data: data['not-found'],
options: {
responsive: true,
legend: {
display: false
display: false,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
beginAtZero: true,
},
}],
},
},
});
new Chart(tooBusyCanvas.getContext('2d'), {
type: 'line',
data: data['toobusy'],
data: data.toobusy,
options: {
responsive: true,
legend: {
display: false
display: false,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
beginAtZero: true,
},
}],
},
},
});
};
return Errors;
});
});

View File

@@ -1,13 +1,10 @@
"use strict";
/* global define, socket, app */
'use strict';
define('admin/advanced/events', function () {
var Events = {};
Events.init = function () {
$('[data-action="clear"]').on('click', function () {
socket.emit('admin.deleteAllEvents', function (err) {
if (err) {
@@ -16,7 +13,6 @@ define('admin/advanced/events', function () {
$('.events-list').empty();
});
});
};
return Events;

View File

@@ -1,5 +1,5 @@
"use strict";
/* global define, socket, app */
'use strict';
define('admin/advanced/logs', function () {
var Logs = {};
@@ -10,30 +10,30 @@ define('admin/advanced/logs', function () {
// Affix menu
$('.affix').affix();
$('.logs').find('button[data-action]').on('click', function (event) {
var btnEl = $(this),
action = btnEl.attr('data-action');
$('.logs').find('button[data-action]').on('click', function () {
var btnEl = $(this);
var action = btnEl.attr('data-action');
switch(action) {
case 'reload':
socket.emit('admin.logs.get', function (err, logs) {
if (!err) {
logsEl.text(logs);
logsEl.scrollTop(logsEl.prop('scrollHeight'));
} else {
app.alertError(err.message);
}
});
break;
switch (action) {
case 'reload':
socket.emit('admin.logs.get', function (err, logs) {
if (!err) {
logsEl.text(logs);
logsEl.scrollTop(logsEl.prop('scrollHeight'));
} else {
app.alertError(err.message);
}
});
break;
case 'clear':
socket.emit('admin.logs.clear', function (err) {
if (!err) {
app.alertSuccess('[[admin/advanced/logs:clear-success]]');
btnEl.prev().click();
}
});
break;
case 'clear':
socket.emit('admin.logs.clear', function (err) {
if (!err) {
app.alertSuccess('[[admin/advanced/logs:clear-success]]');
btnEl.prev().click();
}
});
break;
}
});
};

View File

@@ -1,37 +1,36 @@
"use strict";
/* global ace, define, app, socket */
'use strict';
define('admin/appearance/customise', ['admin/settings'], function (Settings) {
var Customise = {};
Customise.init = function () {
Customise.init = function () {
Settings.prepare(function () {
$('#customCSS').text($('#customCSS-holder').val());
$('#customHTML').text($('#customHTML-holder').val());
var customCSS = ace.edit("customCSS"),
customHTML = ace.edit("customHTML");
customCSS.setTheme("ace/theme/twilight");
customCSS.getSession().setMode("ace/mode/css");
var customCSS = ace.edit('customCSS');
var customHTML = ace.edit('customHTML');
customCSS.on('change', function (event) {
customCSS.setTheme('ace/theme/twilight');
customCSS.getSession().setMode('ace/mode/css');
customCSS.on('change', function () {
app.flags = app.flags || {};
app.flags._unsaved = true;
$('#customCSS-holder').val(customCSS.getValue());
});
$('#customCSS-holder').val(customCSS.getValue());
});
customHTML.setTheme("ace/theme/twilight");
customHTML.getSession().setMode("ace/mode/html");
customHTML.setTheme('ace/theme/twilight');
customHTML.getSession().setMode('ace/mode/html');
customHTML.on('change', function (event) {
customHTML.on('change', function () {
app.flags = app.flags || {};
app.flags._unsaved = true;
$('#customHTML-holder').val(customHTML.getValue());
});
$('#customHTML-holder').val(customHTML.getValue());
});
});
};
return Customise;
});

View File

@@ -1,14 +1,14 @@
"use strict";
/* global define, app, socket, templates */
'use strict';
define('admin/appearance/skins', ['translator'], function (translator) {
var Skins = {};
Skins.init = function () {
// Populate skins from Bootswatch API
$.ajax({
method: 'get',
url: 'https://bootswatch.com/api/3.json'
url: 'https://bootswatch.com/api/3.json',
}).done(Skins.render);
$('#skins').on('click', function (e) {
@@ -21,16 +21,16 @@ define('admin/appearance/skins', ['translator'], function (translator) {
var action = target.attr('data-action');
if (action && action === 'use') {
var parentEl = target.parents('[data-theme]'),
themeType = parentEl.attr('data-type'),
cssSrc = parentEl.attr('data-css'),
themeId = parentEl.attr('data-theme');
var parentEl = target.parents('[data-theme]');
var themeType = parentEl.attr('data-type');
var cssSrc = parentEl.attr('data-css');
var themeId = parentEl.attr('data-theme');
socket.emit('admin.themes.set', {
type: themeType,
id: themeId,
src: cssSrc
src: cssSrc,
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -42,7 +42,7 @@ define('admin/appearance/skins', ['translator'], function (translator) {
type: 'info',
title: '[[admin/appearance/skins:skin-updated]]',
message: themeId ? ('[[admin/appearance/skins:applied-success, ' + themeId + ']]') : '[[admin/appearance/skins:revert-success]]',
timeout: 5000
timeout: 5000,
});
});
}
@@ -62,10 +62,10 @@ define('admin/appearance/skins', ['translator'], function (translator) {
screenshot_url: theme.thumbnail,
url: theme.preview,
css: theme.cssCdn,
skin: true
skin: true,
};
}),
showRevert: true
showRevert: true,
}, function (html) {
translator.translate(html, function (html) {
themeContainer.html(html);
@@ -73,7 +73,7 @@ define('admin/appearance/skins', ['translator'], function (translator) {
if (config['theme:src']) {
var skin = config['theme:src']
.match(/latest\/(\S+)\/bootstrap.min.css/)[1]
.replace(/(^|\s)([a-z])/g , function (m,p1,p2) {return p1 + p2.toUpperCase();});
.replace(/(^|\s)([a-z])/g, function (m, p1, p2) { return p1 + p2.toUpperCase(); });
highlightSelectedTheme(skin);
}

View File

@@ -1,24 +1,24 @@
"use strict";
/* global define, app, socket, bootbox, templates, config */
'use strict';
define('admin/appearance/themes', ['translator'], function (translator) {
var Themes = {};
Themes.init = function () {
$('#installed_themes').on('click', function (e) {
var target = $(e.target),
action = target.attr('data-action');
var target = $(e.target);
var action = target.attr('data-action');
if (action && action === 'use') {
var parentEl = target.parents('[data-theme]'),
themeType = parentEl.attr('data-type'),
cssSrc = parentEl.attr('data-css'),
themeId = parentEl.attr('data-theme');
var parentEl = target.parents('[data-theme]');
var themeType = parentEl.attr('data-type');
var cssSrc = parentEl.attr('data-css');
var themeId = parentEl.attr('data-theme');
socket.emit('admin.themes.set', {
type: themeType,
id: themeId,
src: cssSrc
src: cssSrc,
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -34,18 +34,18 @@ define('admin/appearance/themes', ['translator'], function (translator) {
timeout: 5000,
clickfn: function () {
socket.emit('admin.restart');
}
},
});
});
}
});
$('#revert_theme').on('click', function () {
bootbox.confirm('[[admin/appearance/themes:revert-confirm]]', function (confirm) {
if (confirm) {
socket.emit('admin.themes.set', {
type: 'local',
id: 'nodebb-theme-persona'
id: 'nodebb-theme-persona',
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -56,7 +56,7 @@ define('admin/appearance/themes', ['translator'], function (translator) {
type: 'success',
title: '[[admin/appearance/themes:theme-changed]]',
message: '[[admin/appearance/themes:revert-success]]',
timeout: 3500
timeout: 3500,
});
});
}
@@ -64,7 +64,7 @@ define('admin/appearance/themes', ['translator'], function (translator) {
});
socket.emit('admin.themes.getInstalled', function (err, themes) {
if(err) {
if (err) {
return app.alertError(err.message);
}
@@ -72,10 +72,9 @@ define('admin/appearance/themes', ['translator'], function (translator) {
if (!themes.length) {
instListEl.append($('<li/ >').addClass('no-themes').translateHtml('[[admin/appearance/themes:no-themes]]'));
return;
} else {
templates.parse('admin/partials/theme_list', {
themes: themes
themes: themes,
}, function (html) {
translator.translate(html, function (html) {
instListEl.html(html);

View File

@@ -1,12 +1,12 @@
"use strict";
/* global define, app, socket, bootbox */
'use strict';
define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, translator) {
var Plugins = {};
Plugins.init = function () {
var pluginsList = $('.plugins'),
numPlugins = pluginsList[0].querySelectorAll('li').length,
pluginID;
var pluginsList = $('.plugins');
var numPlugins = pluginsList[0].querySelectorAll('li').length;
var pluginID;
if (!numPlugins) {
translator.translate('<li><p><i>[[admin/extend/plugins:none-found]]</i></p></li>', function (html) {
@@ -29,7 +29,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
btn.html(buttonText);
btn.toggleClass('btn-warning', status.active).toggleClass('btn-success', !status.active);
//clone it to active plugins tab
// clone it to active plugins tab
if (status.active && !$('#active #' + pluginID).length) {
$('#active ul').prepend(pluginEl.clone(true));
}
@@ -44,7 +44,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
require(['admin/modules/instance'], function (instance) {
instance.restart();
});
}
},
});
});
});
@@ -71,21 +71,19 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
return;
}
require(['semver'], function (semver) {
if (payload.version !== 'latest') {
Plugins.toggleInstall(pluginID, payload.version);
} else if (payload.version === 'latest') {
confirmInstall(pluginID, function (confirm) {
if (confirm) {
Plugins.toggleInstall(pluginID, 'latest');
} else {
btn.removeAttr('disabled');
}
});
} else {
btn.removeAttr('disabled');
}
});
if (payload.version !== 'latest') {
Plugins.toggleInstall(pluginID, payload.version);
} else if (payload.version === 'latest') {
confirmInstall(pluginID, function (confirm) {
if (confirm) {
Plugins.toggleInstall(pluginID, 'latest');
} else {
btn.removeAttr('disabled');
}
});
} else {
btn.removeAttr('disabled');
}
});
});
@@ -145,7 +143,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
var plugins = $('#order-active-plugins-modal .plugin-list').children();
var data = [];
plugins.each(function (index, el) {
data.push({name: $(el).text(), order: index});
data.push({ name: $(el).text(), order: index });
});
socket.emit('admin.plugins.orderActivePlugins', data, function (err) {
@@ -162,7 +160,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
function confirmInstall(pluginID, callback) {
bootbox.confirm(translator.compile('admin/extend/plugins:alert.possibly-incompatible', pluginID), function (confirm) {
callback(confirm);
callback(confirm);
});
}
@@ -170,7 +168,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
btn.attr('disabled', true).find('i').attr('class', 'fa fa-refresh fa-spin');
socket.emit('admin.plugins.upgrade', {
id: pluginID,
version: version
version: version,
}, function (err, isActive) {
if (err) {
return app.alertError(err.message);
@@ -190,7 +188,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
require(['admin/modules/instance'], function (instance) {
instance.reload();
});
}
},
});
}
});
@@ -198,12 +196,11 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
Plugins.toggleInstall = function (pluginID, version, callback) {
var btn = $('li[data-plugin-id="' + pluginID + '"] button[data-action="toggleInstall"]');
var activateBtn = btn.siblings('[data-action="toggleActive"]');
btn.find('i').attr('class', 'fa fa-refresh fa-spin');
socket.emit('admin.plugins.toggleInstall', {
id: pluginID,
version: version
version: version,
}, function (err, pluginData) {
if (err) {
btn.removeAttr('disabled');
@@ -217,7 +214,7 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
title: '[[admin/extend/plugins:alert.' + (pluginData.installed ? 'installed' : 'uninstalled') + ']]',
message: '[[admin/extend/plugins:alert.' + (pluginData.installed ? 'install-success' : 'uninstall-success') + ']]',
type: 'info',
timeout: 5000
timeout: 5000,
});
if (typeof callback === 'function') {
@@ -232,9 +229,9 @@ define('admin/extend/plugins', ['jqueryui', 'translator'], function (jqueryui, t
type: 'GET',
data: {
package: pluginId,
version: nbbVersion[0]
version: nbbVersion[0],
},
dataType: 'json'
dataType: 'json',
}).done(function (payload) {
callback(undefined, payload);
}).fail(callback);

View File

@@ -1,14 +1,14 @@
"use strict";
/* global define, app, ajaxify, socket, templates, bootbox */
'use strict';
define('admin/extend/rewards', ['translator'], function (translator) {
var rewards = {};
var available,
active,
conditions,
conditionals;
var available;
var active;
var conditions;
var conditionals;
rewards.init = function () {
available = ajaxify.data.rewards;
@@ -25,10 +25,10 @@ define('admin/extend/rewards', ['translator'], function (translator) {
update($(this));
})
.on('click', '.delete', function () {
var parent = $(this).parents('[data-id]'),
id = parent.attr('data-id');
var parent = $(this).parents('[data-id]');
var id = parent.attr('data-id');
socket.emit('admin.rewards.delete', {id: id}, function (err) {
socket.emit('admin.rewards.delete', { id: id }, function (err) {
if (err) {
app.alertError(err.message);
} else {
@@ -40,10 +40,9 @@ define('admin/extend/rewards', ['translator'], function (translator) {
return false;
})
.on('click', '.toggle', function () {
var btn = $(this),
disabled = btn.hasClass('btn-success'),
id = $(this).parents('[data-id]').attr('data-id');
btn.toggleClass('btn-warning').toggleClass('btn-success').translateHtml('[[admin/extend/rewards:' + disabled ? 'disable' : 'enable' + ']]');
var btn = $(this);
var disabled = btn.hasClass('btn-success');
btn.toggleClass('btn-warning').toggleClass('btn-success').translateHtml('[[admin/extend/rewards:' + (disabled ? 'disable' : 'enable') + ']]');
// send disable api call
return false;
});
@@ -57,26 +56,26 @@ define('admin/extend/rewards', ['translator'], function (translator) {
function select(el) {
el.val(el.attr('data-selected'));
switch (el.attr('name')) {
case 'rid':
selectReward(el);
break;
case 'rid':
selectReward(el);
break;
}
}
function update(el) {
el.attr('data-selected', el.val());
switch (el.attr('name')) {
case 'rid':
selectReward(el);
break;
case 'rid':
selectReward(el);
break;
}
}
function selectReward(el) {
var parent = el.parents('[data-rid]'),
div = parent.find('.inputs'),
inputs,
html = '';
var parent = el.parents('[data-rid]');
var div = parent.find('.inputs');
var inputs;
var html = '';
for (var reward in available) {
if (available.hasOwnProperty(reward)) {
@@ -95,15 +94,15 @@ define('admin/extend/rewards', ['translator'], function (translator) {
inputs.forEach(function (input) {
html += '<label for="' + input.name + '">' + input.label + '<br />';
switch (input.type) {
case 'select':
html += '<select name="' + input.name + '">';
input.values.forEach(function (value) {
html += '<option value="' + value.value + '">' + value.name + '</option>';
});
break;
case 'text':
html += '<input type="text" name="' + input.name + '" />';
break;
case 'select':
html += '<select name="' + input.name + '">';
input.values.forEach(function (value) {
html += '<option value="' + value.value + '">' + value.name + '</option>';
});
break;
case 'text':
html += '<input type="text" name="' + input.name + '" />';
break;
}
html += '</label><br />';
});
@@ -113,8 +112,8 @@ define('admin/extend/rewards', ['translator'], function (translator) {
function populateInputs() {
$('[data-rid]').each(function (i) {
var div = $(this).find('.inputs'),
rewards = active[i].rewards;
var div = $(this).find('.inputs');
var rewards = active[i].rewards;
for (var reward in rewards) {
if (rewards.hasOwnProperty(reward)) {
@@ -133,7 +132,7 @@ define('admin/extend/rewards', ['translator'], function (translator) {
value: '',
claimable: 1,
rid: null,
id: null
id: null,
}],
conditions: conditions,
conditionals: conditionals,
@@ -153,9 +152,9 @@ define('admin/extend/rewards', ['translator'], function (translator) {
var activeRewards = [];
$('#active li').each(function () {
var data = {rewards: {}},
main = $(this).find('form.main').serializeArray(),
rewards = $(this).find('form.rewards').serializeArray();
var data = { rewards: {} };
var main = $(this).find('form.main').serializeArray();
var rewards = $(this).find('form.rewards').serializeArray();
main.forEach(function (obj) {
data[obj.name] = obj.value;

View File

@@ -1,7 +1,7 @@
"use strict";
/* global define, app, socket, bootbox */
'use strict';
define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
define('admin/extend/widgets', ['jqueryui'], function () {
var Widgets = {};
Widgets.init = function () {
@@ -35,7 +35,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
return $(e.target).parents('.widget-panel').clone();
},
distance: 10,
connectToSortable: ".widget-area"
connectToSortable: '.widget-area',
});
$('#widgets .available-containers .containers > [data-container-html]')
@@ -46,7 +46,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
return target.clone().addClass('block').width(target.width()).css('opacity', '0.5');
},
distance: 10
distance: 10,
})
.each(function () {
$(this).attr('data-container-html', $(this).attr('data-container-html').replace(/\\\{([\s\S]*?)\\\}/g, '{$1}'));
@@ -57,7 +57,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
createDatePicker(ui.item);
appendToggle(ui.item);
},
connectWith: "div"
connectWith: 'div',
}).on('click', '.delete-widget', function () {
var panel = $(this).parents('.widget-panel');
@@ -67,7 +67,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
}
});
}).on('mouseup', '> .panel > .panel-heading', function (evt) {
if ( !( $(this).parent().is('.ui-sortable-helper') || $(evt.target).closest('.delete-widget').length ) ) {
if (!($(this).parent().is('.ui-sortable-helper') || $(evt.target).closest('.delete-widget').length)) {
$(this).parent().children('.panel-body').toggleClass('hidden');
}
});
@@ -80,24 +80,26 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
$('#widgets [data-template][data-location]').each(function (i, el) {
el = $(el);
var template = el.attr('data-template'),
location = el.attr('data-location'),
area = el.children('.widget-area'),
widgets = [];
var template = el.attr('data-template');
var location = el.attr('data-location');
var area = el.children('.widget-area');
var widgets = [];
area.find('.widget-panel[data-widget]').each(function () {
var widgetData = {},
data = $(this).find('form').serializeArray();
var widgetData = {};
var data = $(this).find('form').serializeArray();
for (var d in data) {
if (data.hasOwnProperty(d)) {
if (data[d].name) {
if (widgetData[data[d].name]) {
if(!Array.isArray(widgetData[data[d].name])) {
widgetData[data[d].name] = [ widgetData[data[d].name] ];
if (!Array.isArray(widgetData[data[d].name])) {
widgetData[data[d].name] = [
widgetData[data[d].name],
];
}
widgetData[data[d].name].push(data[d].value);
}else{
} else {
widgetData[data[d].name] = data[d].value;
}
}
@@ -106,16 +108,16 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
widgets.push({
widget: $(this).attr('data-widget'),
data: widgetData
data: widgetData,
});
});
socket.emit('admin.widgets.set', {
template: template,
location: location,
widgets: widgets
widgets: widgets,
}, function (err) {
total--;
total -= 1;
if (err) {
app.alertError(err.message);
@@ -127,19 +129,18 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
type: 'success',
title: '[[admin/extend/widgets:alert.updated]]',
message: '[[admin/extend/widgets:alert.update-success]]',
timeout: 2500
timeout: 2500,
});
}
});
});
}
$('.color-selector').on('click', '.btn', function () {
var btn = $(this),
selector = btn.parents('.color-selector'),
container = selector.parents('[data-container-html]'),
classList = [];
var btn = $(this);
var selector = btn.parents('.color-selector');
var container = selector.parents('[data-container-html]');
var classList = [];
selector.children().each(function () {
classList.push($(this).attr('data-class'));
@@ -160,7 +161,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
el.find('.date-selector').datepicker({
changeMonth: true,
changeYear: true,
yearRange: currentYear + ':' + (currentYear + 100)
yearRange: currentYear + ':' + (currentYear + 100),
});
}
@@ -175,7 +176,7 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
el.find('.panel-body .container-html').val(ui.draggable.attr('data-container-html'));
el.find('.panel-body').removeClass('hidden');
},
hoverClass: "panel-info"
hoverClass: 'panel-info',
})
.children('.panel-heading')
.append('<div class="pull-right pointer"><span class="delete-widget"><i class="fa fa-times-circle"></i></span></div><div class="pull-left pointer"><span class="toggle-widget"><i class="fa fa-chevron-circle-down"></i></span>&nbsp;</div>')
@@ -191,8 +192,8 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
}
widget.find('input, textarea, select').each(function () {
var input = $(this),
value = data[input.attr('name')];
var input = $(this);
var value = data[input.attr('name')];
if (input.attr('type') === 'checkbox') {
input.prop('checked', !!value).trigger('change');
@@ -207,15 +208,15 @@ define('admin/extend/widgets', ['jqueryui'], function (jqueryui) {
$.get(RELATIVE_PATH + '/api/admin/extend/widgets', function (data) {
var areas = data.areas;
for(var i = 0; i < areas.length; ++i) {
var area = areas[i],
widgetArea = $('#widgets .area[data-template="' + area.template + '"][data-location="' + area.location + '"]').find('.widget-area');
for (var i = 0; i < areas.length; i += 1) {
var area = areas[i];
var widgetArea = $('#widgets .area[data-template="' + area.template + '"][data-location="' + area.location + '"]').find('.widget-area');
widgetArea.html('');
for (var k = 0; k < area.data.length; ++k) {
var widgetData = area.data[k],
widgetEl = $('.available-widgets [data-widget="' + widgetData.widget + '"]').clone(true).removeClass('hide');
for (var k = 0; k < area.data.length; k += 1) {
var widgetData = area.data[k];
var widgetEl = $('.available-widgets [data-widget="' + widgetData.widget + '"]').clone(true).removeClass('hide');
widgetArea.append(populateWidget(widgetEl, widgetData.data));
appendToggle(widgetEl);

View File

@@ -1,30 +1,32 @@
"use strict";
/*global define, ajaxify, app, socket, utils, bootbox, RELATIVE_PATH*/
'use strict';
define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (semver, Chart, translator) {
var Admin = {};
var intervals = {
rooms: false,
graphs: false
graphs: false,
};
var isMobile = false;
var isPrerelease = /^v?\d+\.\d+\.\d+-.+$/;
var graphData = {
rooms: {},
traffic: {}
traffic: {},
};
var currentGraph = {
units: 'hours',
until: undefined
until: undefined,
};
var DEFAULTS = {
roomInterval: 10000,
graphInterval: 15000,
realtimeInterval: 1500
realtimeInterval: 1500,
};
$(window).on('action:ajaxify.start', function (ev, data) {
var usedTopicColors = [];
$(window).on('action:ajaxify.start', function () {
clearInterval(intervals.rooms);
clearInterval(intervals.graphs);
@@ -37,7 +39,6 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
Admin.init = function () {
app.enterRoom('admin');
socket.emit('admin.rooms.getAll', Admin.updateRoomUsage);
isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
@@ -51,10 +52,10 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
return !isPrerelease.test(version.name); // filter out automated prerelease versions
});
var version = $('#version').html(),
latestVersion = releases[0].name.slice(1),
checkEl = $('.version-check'),
text;
var version = $('#version').html();
var latestVersion = releases[0].name.slice(1);
var checkEl = $('.version-check');
var text;
// Alter box colour accordingly
if (semver.eq(latestVersion, version)) {
@@ -80,8 +81,10 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
$('[data-toggle="tooltip"]').tooltip();
setupRealtimeButton();
setupGraphs();
initiateDashboard();
setupGraphs(function () {
socket.emit('admin.rooms.getAll', Admin.updateRoomUsage);
initiateDashboard();
});
};
Admin.updateRoomUsage = function (err, data) {
@@ -123,51 +126,53 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
traffic: null,
registered: null,
presence: null,
topics: null
topics: null,
};
var topicColors = ["#bf616a","#5B90BF","#d08770","#ebcb8b","#a3be8c","#96b5b4","#8fa1b3","#b48ead","#ab7967","#46BFBD"];
var usedTopicColors = [];
var topicColors = ['#bf616a', '#5B90BF', '#d08770', '#ebcb8b', '#a3be8c', '#96b5b4', '#8fa1b3', '#b48ead', '#ab7967', '#46BFBD'];
/* eslint-disable */
// from chartjs.org
function lighten(col, amt) {
var usePound = false;
if (col[0] == "#") {
if (col[0] === '#') {
col = col.slice(1);
usePound = true;
}
var num = parseInt(col,16);
var num = parseInt(col, 16);
var r = (num >> 16) + amt;
if (r > 255) r = 255;
else if (r < 0) r = 0;
else if (r < 0) r = 0;
var b = ((num >> 8) & 0x00FF) + amt;
if (b > 255) b = 255;
else if (b < 0) b = 0;
else if (b < 0) b = 0;
var g = (num & 0x0000FF) + amt;
if (g > 255) g = 255;
else if (g < 0) g = 0;
return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16);
return (usePound ? '#' : '') + (g | (b << 8) | (r << 16)).toString(16);
}
/* eslint-enable */
function setupGraphs() {
var trafficCanvas = document.getElementById('analytics-traffic'),
registeredCanvas = document.getElementById('analytics-registered'),
presenceCanvas = document.getElementById('analytics-presence'),
topicsCanvas = document.getElementById('analytics-topics'),
trafficCtx = trafficCanvas.getContext('2d'),
registeredCtx = registeredCanvas.getContext('2d'),
presenceCtx = presenceCanvas.getContext('2d'),
topicsCtx = topicsCanvas.getContext('2d'),
trafficLabels = utils.getHoursArray();
function setupGraphs(callback) {
callback = callback || function () {};
var trafficCanvas = document.getElementById('analytics-traffic');
var registeredCanvas = document.getElementById('analytics-registered');
var presenceCanvas = document.getElementById('analytics-presence');
var topicsCanvas = document.getElementById('analytics-topics');
var trafficCtx = trafficCanvas.getContext('2d');
var registeredCtx = registeredCanvas.getContext('2d');
var presenceCtx = presenceCanvas.getContext('2d');
var topicsCtx = topicsCanvas.getContext('2d');
var trafficLabels = utils.getHoursArray();
if (isMobile) {
Chart.defaults.global.tooltips.enabled = false;
@@ -190,25 +195,25 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
datasets: [
{
label: translations[0],
backgroundColor: "rgba(220,220,220,0.2)",
borderColor: "rgba(220,220,220,1)",
pointBackgroundColor: "rgba(220,220,220,1)",
pointHoverBackgroundColor: "#fff",
pointBorderColor: "#fff",
pointHoverBorderColor: "rgba(220,220,220,1)",
data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
backgroundColor: 'rgba(220,220,220,0.2)',
borderColor: 'rgba(220,220,220,1)',
pointBackgroundColor: 'rgba(220,220,220,1)',
pointHoverBackgroundColor: '#fff',
pointBorderColor: '#fff',
pointHoverBorderColor: 'rgba(220,220,220,1)',
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
},
{
label: translations[1],
backgroundColor: "rgba(151,187,205,0.2)",
borderColor: "rgba(151,187,205,1)",
pointBackgroundColor: "rgba(151,187,205,1)",
pointHoverBackgroundColor: "#fff",
pointBorderColor: "#fff",
pointHoverBorderColor: "rgba(151,187,205,1)",
data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
}
]
backgroundColor: 'rgba(151,187,205,0.2)',
borderColor: 'rgba(151,187,205,1)',
pointBackgroundColor: 'rgba(151,187,205,1)',
pointHoverBackgroundColor: '#fff',
pointBorderColor: '#fff',
pointHoverBorderColor: 'rgba(151,187,205,1)',
data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
},
],
};
trafficCanvas.width = $(trafficCanvas).parent().width();
@@ -218,34 +223,34 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
options: {
responsive: true,
legend: {
display: false
display: false,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
beginAtZero: true,
},
}],
},
},
});
graphs.registered = new Chart(registeredCtx, {
type: 'doughnut',
data: {
labels: translations.slice(2, 4),
datasets: [{
data: [1, 1],
backgroundColor: ["#F7464A", "#46BFBD"],
hoverBackgroundColor: ["#FF5A5E", "#5AD3D1"]
}]
backgroundColor: ['#F7464A', '#46BFBD'],
hoverBackgroundColor: ['#FF5A5E', '#5AD3D1'],
}],
},
options: {
responsive: true,
legend: {
display: false
}
}
display: false,
},
},
});
graphs.presence = new Chart(presenceCtx, {
@@ -254,18 +259,18 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
labels: translations.slice(4, 9),
datasets: [{
data: [1, 1, 1, 1, 1],
backgroundColor: ["#F7464A", "#46BFBD", "#FDB45C", "#949FB1", "#9FB194"],
hoverBackgroundColor: ["#FF5A5E", "#5AD3D1", "#FFC870", "#A8B3C5", "#A8B3C5"]
}]
backgroundColor: ['#F7464A', '#46BFBD', '#FDB45C', '#949FB1', '#9FB194'],
hoverBackgroundColor: ['#FF5A5E', '#5AD3D1', '#FFC870', '#A8B3C5', '#A8B3C5'],
}],
},
options: {
responsive: true,
legend: {
display: false
}
}
display: false,
},
},
});
graphs.topics = new Chart(topicsCtx, {
type: 'doughnut',
data: {
@@ -273,15 +278,15 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
datasets: [{
data: [],
backgroundColor: [],
hoverBackgroundColor: []
}]
hoverBackgroundColor: [],
}],
},
options: {
responsive: true,
legend: {
display: false
}
}
display: false,
},
},
});
updateTrafficGraph();
@@ -291,14 +296,16 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
$('[data-action="updateGraph"]').on('click', function () {
var until;
switch($(this).attr('data-until')) {
case 'last-month':
var lastMonth = new Date();
lastMonth.setDate(lastMonth.getDate() - 30);
until = lastMonth.getTime();
switch ($(this).attr('data-until')) {
case 'last-month':
var lastMonth = new Date();
lastMonth.setDate(lastMonth.getDate() - 30);
until = lastMonth.getTime();
}
updateTrafficGraph($(this).attr('data-units'), until);
});
callback();
});
}
@@ -322,7 +329,7 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
socket.emit('admin.analytics.get', {
graph: 'traffic',
units: units || 'hours',
until: until
until: until,
}, function (err, data) {
if (err) {
return app.alertError(err.message);
@@ -371,36 +378,36 @@ define('admin/general/dashboard', ['semver', 'Chart', 'translator'], function (s
graphs.presence.update();
}
function updateTopicsGraph(topics) {
if (!Object.keys(topics).length) {
topics = {"0": {
title: "No users browsing",
value: 1
}};
topics = { 0: {
title: 'No users browsing',
value: 1,
} };
}
var tids = Object.keys(topics);
graphs.topics.data.labels = [];
graphs.topics.data.datasets[0].data = [];
graphs.topics.data.datasets[0].backgroundColor = [];
graphs.topics.data.datasets[0].hoverBackgroundColor = [];
for (var i = 0, ii = tids.length; i < ii; i++) {
for (var i = 0, ii = tids.length; i < ii; i += 1) {
graphs.topics.data.labels.push(topics[tids[i]].title);
graphs.topics.data.datasets[0].data.push(topics[tids[i]].value);
graphs.topics.data.datasets[0].backgroundColor.push(topicColors[i]);
graphs.topics.data.datasets[0].hoverBackgroundColor.push(lighten(topicColors[i], 10));
}
function buildTopicsLegend() {
var legend = $('#topics-legend').html('');
for (var i = 0, ii = tids.length; i < ii; i++) {
for (var i = 0, ii = tids.length; i < ii; i += 1) {
var topic = topics[tids[i]];
var label = topic.value === '0' ? topic.title : '<a title="' + topic.title + '"href="' + RELATIVE_PATH + '/topic/' + tids[i] + '" target="_blank"> ' + topic.title + '</a>';
legend.append(
'<li>' +
'<div style="background-color: ' + topicColors[i] + ';"></div>' +

View File

@@ -1,12 +1,11 @@
"use strict";
/*global define*/
'use strict';
define('admin/general/homepage', ['admin/settings'], function (Settings) {
define('admin/general/homepage', ['admin/settings'], function () {
function toggleCustomRoute() {
if ($('[data-field="homePageRoute"]').val()) {
$('#homePageCustom').hide();
}else{
} else {
$('#homePageCustom').show();
}
}

View File

@@ -1,5 +1,5 @@
"use strict";
/*global define*/
'use strict';
define('admin/general/languages', ['admin/settings'], function (Settings) {
var Languages = {};

View File

@@ -1,9 +1,9 @@
"use strict";
/* global define, app, ajaxify, socket, templates */
'use strict';
define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], function (translator, iconSelect, jqueryui) {
var navigation = {},
available;
define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], function (translator, iconSelect) {
var navigation = {};
var available;
navigation.init = function () {
available = ajaxify.data.available;
@@ -18,12 +18,12 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
connectToSortable: '#active-navigation',
helper: 'clone',
distance: 10,
stop: drop
stop: drop,
});
});
$('#active-navigation').sortable().droppable({
accept: $('#available li .drag-item')
accept: $('#available li .drag-item'),
});
$('#enabled').on('click', '.iconPicker', function () {
@@ -40,8 +40,8 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
$('#active-navigation').on('click', 'li', onSelect);
$('#enabled')
.on('click', '.delete', remove)
.on('click', '.toggle', toggle);
.on('click', '.delete', remove)
.on('click', '.toggle', toggle);
$('#save').on('click', save);
};
@@ -61,14 +61,14 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
}
function drop(ev, ui) {
var id = ui.helper.attr('data-id'),
el = $('#active-navigation [data-id="' + id + '"]'),
data = id === 'custom' ? {iconClass: 'fa-navicon'} : available[id];
var id = ui.helper.attr('data-id');
var el = $('#active-navigation [data-id="' + id + '"]');
var data = id === 'custom' ? { iconClass: 'fa-navicon' } : available[id];
data.enabled = false;
data.index = (parseInt($('#enabled').children().last().attr('data-index'), 10) || 0) + 1;
templates.parse('admin/general/navigation', 'navigation', {navigation: [data]}, function (li) {
templates.parse('admin/general/navigation', 'navigation', { navigation: [data] }, function (li) {
translator.translate(li, function (li) {
li = $(translator.unescape(li));
el.after(li);
@@ -76,12 +76,12 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
});
});
templates.parse('admin/general/navigation', 'enabled', {enabled: [data]}, function (li) {
templates.parse('admin/general/navigation', 'enabled', { enabled: [data] }, function (li) {
translator.translate(li, function (li) {
li = $(translator.unescape(li));
$('#enabled').append(li);
componentHandler.upgradeDom();
});
});
});
}
@@ -95,9 +95,9 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
indices.forEach(function (index) {
var el = $('#enabled').children('[data-index="' + index + '"]');
var form = el.find('form').serializeArray(),
data = {},
properties = {};
var form = el.find('form').serializeArray();
var data = {};
var properties = {};
form.forEach(function (input) {
if (input.name.slice(0, 9) === 'property:' && input.value === 'on') {
@@ -135,8 +135,8 @@ define('admin/general/navigation', ['translator', 'iconSelect', 'jqueryui'], fun
}
function toggle() {
var btn = $(this),
disabled = btn.hasClass('btn-success');
var btn = $(this);
var disabled = btn.hasClass('btn-success');
translator.translate(disabled ? '[[admin/general/navigation:btn.disable]]' : '[[admin/general/navigation:btn.enable]]', function (html) {
btn.toggleClass('btn-warning').toggleClass('btn-success').html(html);
btn.parents('li').find('[name="enabled"]').val(disabled ? 'on' : '');

View File

@@ -1,5 +1,5 @@
"use strict";
/*global define, socket*/
'use strict';
define('admin/general/social', [], function () {
var social = {};
@@ -12,7 +12,7 @@ define('admin/general/social', [], function () {
networks.push($(this).attr('id'));
}
});
socket.emit('admin.social.savePostSharingNetworks', networks, function (err) {
if (err) {
return app.alertError(err);

View File

@@ -1,5 +1,5 @@
"use strict";
/* global app, define, socket */
'use strict';
define('admin/general/sounds', ['sounds', 'settings', 'admin/settings'], function (Sounds, Settings, AdminSettings) {
var SoundsAdmin = {};
@@ -13,20 +13,6 @@ define('admin/general/sounds', ['sounds', 'settings', 'admin/settings'], functio
Sounds.playSound(soundName);
});
// Load Form Values
Settings.load('sounds', $('.sounds form'));
// Saving of Form Values
var saveEl = $('#save');
saveEl.on('click', function () {
Settings.save('sounds', $('.sounds form'), function () {
socket.emit('admin.fireEvent', {
name: 'event:sounds.reloadMapping'
});
app.alertSuccess('[[admin/general/sounds:saved]]');
});
});
AdminSettings.prepare();
};

View File

@@ -1,12 +1,14 @@
"use strict";
/*global define, socket, app, bootbox, templates, ajaxify, Sortable */
'use strict';
define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-serializeobject.min', 'translator'], function (serialize, translator) {
var Categories = {}, newCategoryId = -1, sortables;
var Categories = {};
var newCategoryId = -1;
var sortables;
Categories.init = function () {
socket.emit('admin.categories.getAll', function (error, payload) {
if(error) {
if (error) {
return app.alertError(error.message);
}
@@ -17,10 +19,10 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
// Enable/Disable toggle events
$('.categories').on('click', 'button[data-action="toggle"]', function () {
var $this = $(this),
cid = $this.attr('data-cid'),
parentEl = $this.parents('li[data-cid="' + cid + '"]'),
disabled = parentEl.hasClass('disabled');
var $this = $(this);
var cid = $this.attr('data-cid');
var parentEl = $this.parents('li[data-cid="' + cid + '"]');
var disabled = parentEl.hasClass('disabled');
var children = parentEl.find('li[data-cid]').map(function () {
return $(this).attr('data-cid');
@@ -38,8 +40,20 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
}
templates.parse('admin/partials/categories/create', {
categories: categories
categories: categories,
}, function (html) {
var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.create]]',
message: html,
buttons: {
save: {
label: '[[global:save]]',
className: 'btn-primary',
callback: submit,
},
},
});
function submit() {
var formData = modal.find('form').serializeObject();
formData.description = '';
@@ -50,18 +64,6 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
return false;
}
var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.create]]',
message: html,
buttons: {
save: {
label: '[[global:save]]',
className: 'btn-primary',
callback: submit
}
}
});
modal.find('form').on('submit', submit);
});
});
@@ -78,7 +80,7 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
title: '[[admin/manage/categories:alert.created]]',
message: '[[admin/manage/categories:alert.create-success]]',
type: 'success',
timeout: 2000
timeout: 2000,
});
ajaxify.go('admin/manage/categories/' + data.cid);
@@ -106,7 +108,7 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
cids.forEach(function (cid) {
payload[cid] = {
disabled: disabled ? 1 : 0
disabled: disabled ? 1 : 0,
};
});
@@ -123,16 +125,19 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
}
function itemDragDidEnd(e) {
var isCategoryUpdate = (newCategoryId != -1);
var isCategoryUpdate = parseInt(newCategoryId, 10) !== -1;
//Update needed?
if((e.newIndex != undefined && e.oldIndex != e.newIndex) || isCategoryUpdate) {
var parentCategory = isCategoryUpdate ? sortables[newCategoryId] : sortables[e.from.dataset.cid],
modified = {}, i = 0, list = parentCategory.toArray(), len = list.length;
// Update needed?
if ((e.newIndex != null && parseInt(e.oldIndex, 10) !== parseInt(e.newIndex, 10)) || isCategoryUpdate) {
var parentCategory = isCategoryUpdate ? sortables[newCategoryId] : sortables[e.from.dataset.cid];
var modified = {};
var i = 0;
var list = parentCategory.toArray();
var len = list.length;
for(i; i < len; ++i) {
for (i; i < len; i += 1) {
modified[list[i]] = {
order: (i + 1)
order: (i + 1),
};
}
@@ -161,7 +166,7 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
if (category.name !== translated) {
category.name = translated;
}
++count;
count += 1;
if (count === parent.length) {
continueRender();
@@ -176,13 +181,13 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
function continueRender() {
templates.parse('admin/partials/categories/category-rows', {
cid: parentId,
categories: categories
categories: categories,
}, function (html) {
translator.translate(html, function (html) {
container.append(html);
// Handle and children categories in this level have
for(var x = 0,numCategories = categories.length; x < numCategories; x++) {
for (var x = 0, numCategories = categories.length; x < numCategories; x += 1) {
renderList(categories[x].children, $('li[data-cid="' + categories[x].cid + '"]'), categories[x].cid);
}
@@ -192,9 +197,9 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
animation: 150,
handle: '.icon',
dataIdAttr: 'data-cid',
ghostClass: "placeholder",
ghostClass: 'placeholder',
onAdd: itemDidAdd,
onEnd: itemDragDidEnd
onEnd: itemDragDidEnd,
});
});
});
@@ -202,4 +207,4 @@ define('admin/manage/categories', ['vendor/jquery/serializeObject/jquery.ba-seri
}
return Categories;
});
});

View File

@@ -1,5 +1,5 @@
"use strict";
/*global define, ajaxify, utils */
'use strict';
define('admin/manage/category-analytics', ['Chart'], function (Chart) {
var CategoryAnalytics = {};
@@ -10,11 +10,11 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
var topicsCanvas = document.getElementById('topics:daily');
var postsCanvas = document.getElementById('posts:daily');
var hourlyLabels = utils.getHoursArray().map(function (text, idx) {
return idx % 3 ? '' : text;
});
return idx % 3 ? '' : text;
});
var dailyLabels = utils.getDaysArray().map(function (text, idx) {
return idx % 3 ? '' : text;
});
return idx % 3 ? '' : text;
});
if (utils.isMobile()) {
Chart.defaults.global.tooltips.enabled = false;
@@ -25,69 +25,69 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
labels: hourlyLabels,
datasets: [
{
label: "",
backgroundColor: "rgba(186,139,175,0.2)",
borderColor: "rgba(186,139,175,1)",
pointBackgroundColor: "rgba(186,139,175,1)",
pointHoverBackgroundColor: "#fff",
pointBorderColor: "#fff",
pointHoverBorderColor: "rgba(186,139,175,1)",
data: ajaxify.data.analytics['pageviews:hourly']
}
]
label: '',
backgroundColor: 'rgba(186,139,175,0.2)',
borderColor: 'rgba(186,139,175,1)',
pointBackgroundColor: 'rgba(186,139,175,1)',
pointHoverBackgroundColor: '#fff',
pointBorderColor: '#fff',
pointHoverBorderColor: 'rgba(186,139,175,1)',
data: ajaxify.data.analytics['pageviews:hourly'],
},
],
},
'pageviews:daily': {
labels: dailyLabels,
datasets: [
{
label: "",
backgroundColor: "rgba(151,187,205,0.2)",
borderColor: "rgba(151,187,205,1)",
pointBackgroundColor: "rgba(151,187,205,1)",
pointHoverBackgroundColor: "#fff",
pointBorderColor: "#fff",
pointHoverBorderColor: "rgba(151,187,205,1)",
data: ajaxify.data.analytics['pageviews:daily']
}
]
label: '',
backgroundColor: 'rgba(151,187,205,0.2)',
borderColor: 'rgba(151,187,205,1)',
pointBackgroundColor: 'rgba(151,187,205,1)',
pointHoverBackgroundColor: '#fff',
pointBorderColor: '#fff',
pointHoverBorderColor: 'rgba(151,187,205,1)',
data: ajaxify.data.analytics['pageviews:daily'],
},
],
},
'topics:daily': {
labels: dailyLabels.slice(-7),
datasets: [
{
label: "",
backgroundColor: "rgba(171,70,66,0.2)",
borderColor: "rgba(171,70,66,1)",
pointBackgroundColor: "rgba(171,70,66,1)",
pointHoverBackgroundColor: "#fff",
pointBorderColor: "#fff",
pointHoverBorderColor: "rgba(171,70,66,1)",
data: ajaxify.data.analytics['topics:daily']
}
]
label: '',
backgroundColor: 'rgba(171,70,66,0.2)',
borderColor: 'rgba(171,70,66,1)',
pointBackgroundColor: 'rgba(171,70,66,1)',
pointHoverBackgroundColor: '#fff',
pointBorderColor: '#fff',
pointHoverBorderColor: 'rgba(171,70,66,1)',
data: ajaxify.data.analytics['topics:daily'],
},
],
},
'posts:daily': {
labels: dailyLabels.slice(-7),
datasets: [
{
label: "",
backgroundColor: "rgba(161,181,108,0.2)",
borderColor: "rgba(161,181,108,1)",
pointBackgroundColor: "rgba(161,181,108,1)",
pointHoverBackgroundColor: "#fff",
pointBorderColor: "#fff",
pointHoverBorderColor: "rgba(161,181,108,1)",
data: ajaxify.data.analytics['posts:daily']
}
]
}
label: '',
backgroundColor: 'rgba(161,181,108,0.2)',
borderColor: 'rgba(161,181,108,1)',
pointBackgroundColor: 'rgba(161,181,108,1)',
pointHoverBackgroundColor: '#fff',
pointBorderColor: '#fff',
pointHoverBorderColor: 'rgba(161,181,108,1)',
data: ajaxify.data.analytics['posts:daily'],
},
],
},
};
hourlyCanvas.width = $(hourlyCanvas).parent().width();
dailyCanvas.width = $(dailyCanvas).parent().width();
topicsCanvas.width = $(topicsCanvas).parent().width();
postsCanvas.width = $(postsCanvas).parent().width();
new Chart(hourlyCanvas.getContext('2d'), {
type: 'line',
data: data['pageviews:hourly'],
@@ -95,18 +95,18 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
responsive: true,
animation: false,
legend: {
display: false
display: false,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
beginAtZero: true,
},
}],
},
},
});
new Chart(dailyCanvas.getContext('2d'), {
type: 'line',
data: data['pageviews:daily'],
@@ -114,18 +114,18 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
responsive: true,
animation: false,
legend: {
display: false
display: false,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
beginAtZero: true,
},
}],
},
},
});
new Chart(topicsCanvas.getContext('2d'), {
type: 'line',
data: data['topics:daily'],
@@ -133,18 +133,18 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
responsive: true,
animation: false,
legend: {
display: false
display: false,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
beginAtZero: true,
},
}],
},
},
});
new Chart(postsCanvas.getContext('2d'), {
type: 'line',
data: data['posts:daily'],
@@ -152,18 +152,18 @@ define('admin/manage/category-analytics', ['Chart'], function (Chart) {
responsive: true,
animation: false,
legend: {
display: false
display: false,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
beginAtZero: true,
},
}],
},
},
});
};
return CategoryAnalytics;
});
});

View File

@@ -1,12 +1,12 @@
"use strict";
/*global config, define, app, socket, ajaxify, bootbox, templates */
'use strict';
define('admin/manage/category', [
'uploader',
'iconSelect',
'admin/modules/colorpicker',
'autocomplete',
'translator'
'translator',
], function (uploader, iconSelect, colorpicker, autocomplete, translator) {
var Category = {};
var modified_categories = {};
@@ -26,40 +26,14 @@ define('admin/manage/category', [
}
}
function save(e) {
e.preventDefault();
if(Object.keys(modified_categories).length) {
socket.emit('admin.categories.update', modified_categories, function (err, results) {
if (err) {
return app.alertError(err.message);
}
if (results && results.length) {
app.flags._unsaved = false;
app.alert({
title: '[[admin/manage/categories:alert.updated]]',
message: translator.compile(
'admin/manage/categories:alert.updated-success',
results.join('&#44; ')
),
type: 'success',
timeout: 2000
});
}
});
modified_categories = {};
}
}
$('.blockclass, form.category select').each(function () {
var $this = $(this);
$this.val($this.attr('data-value'));
});
function enableColorPicker(idx, inputEl) {
var $inputEl = $(inputEl),
previewEl = $inputEl.parents('[data-cid]').find('.category-preview');
var $inputEl = $(inputEl);
var previewEl = $inputEl.parents('[data-cid]').find('.category-preview');
colorpicker.enable($inputEl, function (hsb, hex) {
if ($inputEl.attr('data-name') === 'bgColor') {
@@ -103,7 +77,7 @@ define('admin/manage/category', [
title: 'Updated Categories',
message: 'Category IDs ' + result.join(', ') + ' was successfully updated.',
type: 'success',
timeout: 2000
timeout: 2000,
});
}
});
@@ -134,7 +108,7 @@ define('admin/manage/category', [
$('.copy-settings').on('click', function () {
selectCategoryModal(function (cid) {
socket.emit('admin.categories.copySettingsFrom', {fromCid: cid, toCid: ajaxify.data.category.cid}, function (err) {
socket.emit('admin.categories.copySettingsFrom', { fromCid: cid, toCid: ajaxify.data.category.cid }, function (err) {
if (err) {
return app.alertError(err.message);
}
@@ -152,7 +126,7 @@ define('admin/manage/category', [
uploader.show({
title: '[[admin/manage/categories:alert.upload-image]]',
route: config.relative_path + '/api/admin/category/uploadpicture',
params: {cid: cid}
params: { cid: cid },
}, function (imageUrlOnServer) {
$('#category-image').val(imageUrlOnServer);
var previewBox = inputEl.parent().parent().siblings('.category-preview');
@@ -186,7 +160,7 @@ define('admin/manage/category', [
$('button[data-action="removeParent"]').on('click', function () {
var payload = {};
payload[ajaxify.data.category.cid] = {
parentCid: 0
parentCid: 0,
};
socket.emit('admin.categories.update', payload, function (err) {
@@ -220,26 +194,26 @@ define('admin/manage/category', [
var tagEl = $('#tag-whitelist');
tagEl.tagsinput({
confirmKeys: [13, 44],
trimValue: true
trimValue: true,
});
ajaxify.data.category.tagWhitelist.forEach(function (tag) {
tagEl.tagsinput('add', tag);
});
tagEl.on('itemAdded itemRemoved', function (event) {
tagEl.on('itemAdded itemRemoved', function () {
modified(tagEl);
});
}
Category.setupPrivilegeTable = function () {
$('.privilege-table-container').on('change', 'input[type="checkbox"]', function () {
var checkboxEl = $(this),
privilege = checkboxEl.parent().attr('data-privilege'),
state = checkboxEl.prop('checked'),
rowEl = checkboxEl.parents('tr'),
member = rowEl.attr('data-group-name') || rowEl.attr('data-uid'),
isPrivate = parseInt(rowEl.attr('data-private') || 0, 10),
isGroup = rowEl.attr('data-group-name') !== undefined;
var checkboxEl = $(this);
var privilege = checkboxEl.parent().attr('data-privilege');
var state = checkboxEl.prop('checked');
var rowEl = checkboxEl.parents('tr');
var member = rowEl.attr('data-group-name') || rowEl.attr('data-uid');
var isPrivate = parseInt(rowEl.attr('data-private') || 0, 10);
var isGroup = rowEl.attr('data-group-name') !== undefined;
if (member) {
if (isGroup && privilege === 'groups:moderate' && !isPrivate && state) {
@@ -247,7 +221,7 @@ define('admin/manage/category', [
if (confirm) {
Category.setPrivilege(member, privilege, state, checkboxEl);
} else {
checkboxEl.prop('checked', checkboxEl.prop('checked') ^ 1);
checkboxEl.prop('checked', !checkboxEl.prop('checked'));
}
});
} else {
@@ -273,7 +247,7 @@ define('admin/manage/category', [
}
templates.parse('admin/partials/categories/privileges', {
privileges: privileges
privileges: privileges,
}, function (html) {
translator.translate(html, function (html) {
$('.privilege-table-container').html(html);
@@ -295,7 +269,7 @@ define('admin/manage/category', [
privs.push(el.getAttribute('data-privilege'));
}
});
for(var x = 0,numPrivs = privs.length; x < numPrivs; x++) {
for (var x = 0, numPrivs = privs.length; x < numPrivs; x += 1) {
var inputs = $('.privilege-table tr[data-group-name]:not([data-group-name="registered-users"],[data-group-name="guests"]) td[data-privilege="' + privs[x] + '"] input');
inputs.each(function (idx, el) {
if (!el.checked) {
@@ -310,7 +284,7 @@ define('admin/manage/category', [
cid: ajaxify.data.category.cid,
privilege: privilege,
set: state,
member: member
member: member,
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -332,19 +306,19 @@ define('admin/manage/category', [
});
templates.parse('partials/category_list', {
categories: categories
categories: categories,
}, function (html) {
var modal = bootbox.dialog({
message: html,
title: '[[admin/manage/categories:alert.set-parent-category]]'
title: '[[admin/manage/categories:alert.set-parent-category]]',
});
modal.find('li[data-cid]').on('click', function () {
var parentCid = $(this).attr('data-cid'),
payload = {};
var parentCid = $(this).attr('data-cid');
var payload = {};
payload[ajaxify.data.category.cid] = {
parentCid: parentCid
parentCid: parentCid,
};
socket.emit('admin.categories.update', payload, function (err) {
@@ -371,7 +345,7 @@ define('admin/manage/category', [
var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.find-user]]',
message: '<input class="form-control input-lg" placeholder="[[admin/manage/categories:alert.user-search]]" />',
show: true
show: true,
});
modal.on('shown.bs.modal', function () {
@@ -382,7 +356,7 @@ define('admin/manage/category', [
cid: ajaxify.data.category.cid,
privilege: ['find', 'read', 'topics:read'],
set: true,
member: ui.item.user.uid
member: ui.item.user.uid,
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -399,7 +373,7 @@ define('admin/manage/category', [
var modal = bootbox.dialog({
title: '[[admin/manage/categories:alert.find-group]]',
message: '<input class="form-control input-lg" placeholder="[[admin/manage/categories:alert.group-search]]" />',
show: true
show: true,
});
modal.on('shown.bs.modal', function () {
@@ -410,7 +384,7 @@ define('admin/manage/category', [
cid: ajaxify.data.category.cid,
privilege: ['groups:find', 'groups:read', 'groups:topics:read'],
set: true,
member: ui.item.group.name
member: ui.item.group.name,
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -434,7 +408,7 @@ define('admin/manage/category', [
Category.copyPrivilegesFromCategory = function () {
selectCategoryModal(function (cid) {
socket.emit('admin.categories.copyPrivilegesFrom', {toCid: ajaxify.data.category.cid, fromCid: cid}, function (err) {
socket.emit('admin.categories.copyPrivilegesFrom', { toCid: ajaxify.data.category.cid, fromCid: cid }, function (err) {
if (err) {
return app.alertError(err.message);
}
@@ -450,16 +424,9 @@ define('admin/manage/category', [
}
templates.parse('admin/partials/categories/select-category', {
categories: categories
categories: categories,
}, function (html) {
translator.translate(html, function (html) {
function submit() {
var formData = modal.find('form').serializeObject();
callback(formData['select-cid']);
modal.modal('hide');
return false;
}
var modal = bootbox.dialog({
title: 'Select a Category',
message: html,
@@ -467,11 +434,18 @@ define('admin/manage/category', [
save: {
label: 'Copy',
className: 'btn-primary',
callback: submit
}
}
callback: submit,
},
},
});
function submit() {
var formData = modal.find('form').serializeObject();
callback(formData['select-cid']);
modal.modal('hide');
return false;
}
modal.find('form').on('submit', submit);
});
});
@@ -480,4 +454,4 @@ define('admin/manage/category', [
return Category;
});
});

View File

@@ -1,13 +1,12 @@
"use strict";
/*global define, socket, app, utils, bootbox, ajaxify*/
'use strict';
define('admin/manage/flags', [
'autocomplete',
'Chart',
'components',
'translator'
'translator',
], function (autocomplete, Chart, components, translator) {
var Flags = {};
Flags.init = function () {
@@ -38,7 +37,7 @@ define('admin/manage/flags', [
socket.emit('posts.dismissFlag', pid, function (err) {
done(err, btn);
});
});
});
}
function handleDismissAll() {
@@ -63,7 +62,7 @@ define('admin/manage/flags', [
}
var pid = btn.parents('[data-pid]').attr('data-pid');
var tid = btn.parents('[data-pid]').attr('data-tid');
socket.emit('posts.delete', {pid: pid, tid: tid}, function (err) {
socket.emit('posts.delete', { pid: pid, tid: tid }, function (err) {
done(err, btn);
});
});
@@ -98,17 +97,17 @@ define('admin/manage/flags', [
labels: dailyLabels,
datasets: [
{
label: "",
backgroundColor: "rgba(151,187,205,0.2)",
borderColor: "rgba(151,187,205,1)",
pointBackgroundColor: "rgba(151,187,205,1)",
pointHoverBackgroundColor: "#fff",
pointBorderColor: "#fff",
pointHoverBorderColor: "rgba(151,187,205,1)",
data: ajaxify.data.analytics
}
]
}
label: '',
backgroundColor: 'rgba(151,187,205,0.2)',
borderColor: 'rgba(151,187,205,1)',
pointBackgroundColor: 'rgba(151,187,205,1)',
pointHoverBackgroundColor: '#fff',
pointBorderColor: '#fff',
pointHoverBorderColor: 'rgba(151,187,205,1)',
data: ajaxify.data.analytics,
},
],
},
};
dailyCanvas.width = $(dailyCanvas).parent().width();
@@ -119,21 +118,21 @@ define('admin/manage/flags', [
responsive: true,
animation: false,
legend: {
display: false
display: false,
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
beginAtZero: true,
},
}],
},
},
});
}
function updateFlagDetails(source) {
// As the flag details are returned in the API,
// As the flag details are returned in the API,
// update the form controls to show the correct data
// Create reference hash for use in this method
@@ -147,7 +146,7 @@ define('admin/manage/flags', [
el = $(el);
if (source[pid]) {
for(var prop in source[pid]) {
for (var prop in source[pid]) {
if (source[pid].hasOwnProperty(prop)) {
el.find('[name="' + prop + '"]').val(source[pid][prop]);
}
@@ -162,15 +161,14 @@ define('admin/manage/flags', [
socket.emit('posts.updateFlag', {
pid: pid,
data: formData
data: formData,
}, function (err) {
if (err) {
return app.alertError(err.message);
} else {
app.alertSuccess('[[topic:flag_manage_saved]]');
}
app.alertSuccess('[[topic:flag_manage_saved]]');
});
}
return Flags;
});
});

View File

@@ -1,22 +1,22 @@
"use strict";
/*global define, templates, socket, ajaxify, app, bootbox */
'use strict';
define('admin/manage/group', [
'forum/groups/memberlist',
'iconSelect',
'admin/modules/colorpicker',
'translator'
'translator',
], function (memberList, iconSelect, colorpicker, translator) {
var Groups = {};
Groups.init = function () {
var groupDetailsSearch = $('#group-details-search'),
groupDetailsSearchResults = $('#group-details-search-results'),
groupIcon = $('#group-icon'),
changeGroupUserTitle = $('#change-group-user-title'),
changeGroupLabelColor = $('#change-group-label-color'),
groupLabelPreview = $('#group-label-preview'),
searchDelay;
var groupDetailsSearch = $('#group-details-search');
var groupDetailsSearchResults = $('#group-details-search-results');
var groupIcon = $('#group-icon');
var changeGroupUserTitle = $('#change-group-user-title');
var changeGroupLabelColor = $('#change-group-label-color');
var groupLabelPreview = $('#group-label-preview');
var searchDelay;
var groupName = ajaxify.data.group.name;
@@ -32,28 +32,27 @@ define('admin/manage/group', [
});
groupDetailsSearch.on('keyup', function () {
if (searchDelay) {
clearTimeout(searchDelay);
}
searchDelay = setTimeout(function () {
var searchText = groupDetailsSearch.val(),
foundUser;
var searchText = groupDetailsSearch.val();
var foundUser;
socket.emit('admin.user.search', {
query: searchText
query: searchText,
}, function (err, results) {
if (!err && results && results.users.length > 0) {
var numResults = results.users.length,
x;
var numResults = results.users.length;
var x;
if (numResults > 20) {
numResults = 20;
}
groupDetailsSearchResults.empty();
for (x = 0; x < numResults; x++) {
for (x = 0; x < numResults; x += 1) {
foundUser = $('<li />');
foundUser
.attr({
@@ -63,7 +62,7 @@ define('admin/manage/group', [
'data-userslug': results.users[x].userslug,
'data-picture': results.users[x].picture,
'data-usericon-bgColor': results.users[x]['icon:bgColor'],
'data-usericon-text': results.users[x]['icon:text']
'data-usericon-text': results.users[x]['icon:text'],
})
.append(results.users[x].picture ?
$('<img />').addClass('avatar avatar-sm').attr('src', results.users[x].picture) :
@@ -80,12 +79,12 @@ define('admin/manage/group', [
});
groupDetailsSearchResults.on('click', 'li[data-uid]', function () {
var userLabel = $(this),
uid = parseInt(userLabel.attr('data-uid'), 10);
var userLabel = $(this);
var uid = parseInt(userLabel.attr('data-uid'), 10);
socket.emit('admin.groups.join', {
groupName: groupName,
uid: uid
uid: uid,
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -96,15 +95,15 @@ define('admin/manage/group', [
username: userLabel.attr('data-username'),
userslug: userLabel.attr('data-userslug'),
picture: userLabel.attr('data-picture'),
"icon:bgColor": userLabel.attr('data-usericon-bgColor'),
"icon:text": userLabel.attr('data-usericon-text')
'icon:bgColor': userLabel.attr('data-usericon-bgColor'),
'icon:text': userLabel.attr('data-usericon-text'),
};
templates.parse('admin/partials/groups/memberlist', 'members', {
group: {
isOwner: ajaxify.data.group.isOwner,
members: [member]
}
members: [member],
},
}, function (html) {
translator.translate(html, function (html) {
$('[component="groups/members"] tbody').prepend(html);
@@ -114,18 +113,18 @@ define('admin/manage/group', [
});
$('[component="groups/members"]').on('click', '[data-action]', function () {
var btnEl = $(this),
userRow = btnEl.parents('[data-uid]'),
ownerFlagEl = userRow.find('.member-name i'),
isOwner = !ownerFlagEl.hasClass('invisible') ? true : false,
uid = userRow.attr('data-uid'),
action = btnEl.attr('data-action');
var btnEl = $(this);
var userRow = btnEl.parents('[data-uid]');
var ownerFlagEl = userRow.find('.member-name i');
var isOwner = !ownerFlagEl.hasClass('invisible');
var uid = userRow.attr('data-uid');
var action = btnEl.attr('data-action');
switch (action) {
case 'toggleOwnership':
socket.emit('groups.' + (isOwner ? 'rescind' : 'grant'), {
toUid: uid,
groupName: groupName
groupName: groupName,
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -141,14 +140,13 @@ define('admin/manage/group', [
}
socket.emit('admin.groups.leave', {
uid: uid,
groupName: groupName
groupName: groupName,
}, function (err) {
if (err) {
return app.alertError(err.message);
}
userRow.slideUp().remove();
});
});
break;
default:
@@ -176,8 +174,8 @@ define('admin/manage/group', [
userTitleEnabled: $('#group-userTitleEnabled').is(':checked'),
private: $('#group-private').is(':checked'),
hidden: $('#group-hidden').is(':checked'),
disableJoinRequests: $('#group-disableJoinRequests').is(':checked')
}
disableJoinRequests: $('#group-disableJoinRequests').is(':checked'),
},
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -194,7 +192,6 @@ define('admin/manage/group', [
});
return false;
});
};
return Groups;

View File

@@ -1,5 +1,5 @@
"use strict";
/*global define, templates, socket, ajaxify, app, admin, bootbox, utils, config */
'use strict';
define('admin/manage/groups', ['translator'], function (translator) {
var Groups = {};
@@ -7,10 +7,10 @@ define('admin/manage/groups', ['translator'], function (translator) {
var intervalId = 0;
Groups.init = function () {
var createModal = $('#create-modal'),
createGroupName = $('#create-group-name'),
createModalGo = $('#create-modal-go'),
createModalError = $('#create-modal-error');
var createModal = $('#create-modal');
var createGroupName = $('#create-group-name');
var createModalGo = $('#create-modal-go');
var createModalError = $('#create-modal-error');
handleSearch();
@@ -29,10 +29,9 @@ define('admin/manage/groups', ['translator'], function (translator) {
createModalGo.on('click', function () {
var submitObj = {
name: createGroupName.val(),
description: $('#create-group-desc').val()
},
errorText;
name: createGroupName.val(),
description: $('#create-group-desc').val(),
};
socket.emit('admin.groups.create', submitObj, function (err) {
if (err) {
@@ -52,18 +51,18 @@ define('admin/manage/groups', ['translator'], function (translator) {
});
$('.groups-list').on('click', 'button[data-action]', function () {
var el = $(this),
action = el.attr('data-action'),
groupName = el.parents('tr[data-groupname]').attr('data-groupname');
var el = $(this);
var action = el.attr('data-action');
var groupName = el.parents('tr[data-groupname]').attr('data-groupname');
switch (action) {
case 'delete':
bootbox.confirm('[[admin/manage/groups:alerts.confirm-delete]]', function (confirm) {
if (confirm) {
socket.emit('groups.delete', {
groupName: groupName
}, function (err, data) {
if(err) {
groupName: groupName,
}, function (err) {
if (err) {
return app.alertError(err.message);
}
@@ -77,6 +76,8 @@ define('admin/manage/groups', ['translator'], function (translator) {
};
function handleSearch() {
var queryEl = $('#group-search');
function doSearch() {
if (!queryEl.val()) {
return ajaxify.refresh();
@@ -86,15 +87,15 @@ define('admin/manage/groups', ['translator'], function (translator) {
socket.emit('groups.search', {
query: queryEl.val(),
options: {
sort: 'date'
}
sort: 'date',
},
}, function (err, groups) {
if (err) {
return app.alertError(err.message);
}
templates.parse('admin/manage/groups', 'groups', {
groups: groups
groups: groups,
}, function (html) {
translator.translate(html, function (html) {
groupsEl.find('[data-groupname]').remove();
@@ -104,8 +105,6 @@ define('admin/manage/groups', ['translator'], function (translator) {
});
}
var queryEl = $('#group-search');
queryEl.on('keyup', function () {
if (intervalId) {
clearTimeout(intervalId);

View File

@@ -1,15 +1,14 @@
'use strict';
/* globals $, app, socket, templates, define, bootbox */
define('admin/manage/ip-blacklist', ['translator'], function (translator) {
define('admin/manage/ip-blacklist', [], function () {
var Blacklist = {};
Blacklist.init = function () {
var blacklist = $('#blacklist-rules');
blacklist.on('keyup', function () {
$('#blacklist-rules-holder').val(blacklist.val());
$('#blacklist-rules-holder').val(blacklist.val());
});
$('[data-action="apply"]').on('click', function () {
@@ -27,7 +26,7 @@ define('admin/manage/ip-blacklist', ['translator'], function (translator) {
$('[data-action="test"]').on('click', function () {
socket.emit('blacklist.validate', {
rules: blacklist.val()
rules: blacklist.val(),
}, function (err, data) {
if (err) {
return app.alertError(err.message);
@@ -41,4 +40,4 @@ define('admin/manage/ip-blacklist', ['translator'], function (translator) {
};
return Blacklist;
});
});

View File

@@ -1,19 +1,17 @@
"use strict";
'use strict';
/* global config, socket, define, templates, bootbox, app, ajaxify, */
define('admin/manage/registration', function () {
var Registration = {};
Registration.init = function () {
$('.users-list').on('click', '[data-action]', function (ev) {
$('.users-list').on('click', '[data-action]', function () {
var parent = $(this).parents('[data-username]');
var action = $(this).attr('data-action');
var username = parent.attr('data-username');
var method = action === 'accept' ? 'admin.user.acceptRegistration' : 'admin.user.rejectRegistration';
socket.emit(method, {username: username}, function (err) {
socket.emit(method, { username: username }, function (err) {
if (err) {
return app.alertError(err.message);
}
@@ -22,7 +20,7 @@ define('admin/manage/registration', function () {
return false;
});
$('.invites-list').on('click', '[data-action]', function (ev) {
$('.invites-list').on('click', '[data-action]', function () {
var parent = $(this).parents('[data-invitation-mail][data-invited-by]');
var email = parent.attr('data-invitation-mail');
var invitedBy = parent.attr('data-invited-by');
@@ -30,9 +28,9 @@ define('admin/manage/registration', function () {
var method = 'admin.user.deleteInvitation';
var removeRow = function () {
var nextRow = parent.next(),
thisRowinvitedBy = parent.find('.invited-by'),
nextRowInvitedBy = nextRow.find('.invited-by');
var nextRow = parent.next();
var thisRowinvitedBy = parent.find('.invited-by');
var nextRowInvitedBy = nextRow.find('.invited-by');
if (nextRowInvitedBy.html() !== undefined && nextRowInvitedBy.html().length < 2) {
nextRowInvitedBy.html(thisRowinvitedBy.html());
}
@@ -41,7 +39,7 @@ define('admin/manage/registration', function () {
if (action === 'delete') {
bootbox.confirm('[[admin/manage/registration:invitations.confirm-delete]]', function (confirm) {
if (confirm) {
socket.emit(method, {email: email, invitedBy: invitedBy}, function (err) {
socket.emit(method, { email: email, invitedBy: invitedBy }, function (err) {
if (err) {
return app.alertError(err.message);
}

View File

@@ -1,13 +1,13 @@
"use strict";
/*global define, socket, app, utils, bootbox, ajaxify*/
'use strict';
define('admin/manage/tags', [
'forum/infinitescroll',
'admin/modules/selectable',
'admin/modules/colorpicker'
'admin/modules/colorpicker',
], function (infinitescroll, selectable, colorpicker) {
var Tags = {},
timeoutId = 0;
var Tags = {};
var timeoutId = 0;
Tags.init = function () {
selectable.enable('.tag-management', '.tag-row');
@@ -38,7 +38,7 @@ define('admin/manage/tags', [
createModalGo.on('click', function () {
socket.emit('admin.tags.create', {
tag: createTagName.val()
tag: createTagName.val(),
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -62,14 +62,14 @@ define('admin/manage/tags', [
timeoutId = setTimeout(function () {
socket.emit('topics.searchAndLoadTags', {
query: $('#tag-search').val()
query: $('#tag-search').val(),
}, function (err, result) {
if (err) {
return app.alertError(err.message);
}
app.parseAndTranslate('admin/manage/tags', 'tags', {
tags: result.tags
tags: result.tags,
}, function (html) {
$('.tag-list').html(html);
utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
@@ -89,20 +89,20 @@ define('admin/manage/tags', [
return;
}
var firstTag = $(tagsToModify[0]),
title = tagsToModify.length > 1 ? '[[admin/manage/tags:alerts.editing-multiple]]' : '[[admin/manage/tags:alerts.editing-x, ' + firstTag.find('.tag-item').attr('data-tag') + ']]';
var firstTag = $(tagsToModify[0]);
var title = tagsToModify.length > 1 ? '[[admin/manage/tags:alerts.editing-multiple]]' : '[[admin/manage/tags:alerts.editing-x, ' + firstTag.find('.tag-item').attr('data-tag') + ']]';
var modal = bootbox.dialog({
title: title,
message: firstTag.find('.tag-modal').html(),
buttons: {
success: {
label: "Save",
className: "btn-primary save",
label: 'Save',
className: 'btn-primary save',
callback: function () {
var modal = $('.bootbox'),
bgColor = modal.find('[data-name="bgColor"]').val(),
color = modal.find('[data-name="color"]').val();
var modal = $('.bootbox');
var bgColor = modal.find('[data-name="bgColor"]').val();
var color = modal.find('[data-name="color"]').val();
tagsToModify.each(function (idx, tag) {
tag = $(tag);
@@ -113,9 +113,9 @@ define('admin/manage/tags', [
save(tag);
});
}
}
}
},
},
},
});
handleColorPickers(modal);
@@ -138,7 +138,7 @@ define('admin/manage/tags', [
tags.push($(el).attr('data-tag'));
});
socket.emit('admin.tags.deleteTags', {
tags: tags
tags: tags,
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -162,7 +162,7 @@ define('admin/manage/tags', [
var data = {
tag: tag.attr('data-tag'),
bgColor: tag.find('[data-name="bgColor"]').val(),
color: tag.find('[data-name="color"]').val()
color: tag.find('[data-name="color"]').val(),
};
socket.emit('admin.tags.update', data, function (err) {

View File

@@ -1,6 +1,5 @@
"use strict";
'use strict';
/* global config, socket, define, templates, bootbox, app, ajaxify */
define('admin/manage/users', ['translator'], function (translator) {
var Users = {};
@@ -91,7 +90,7 @@ define('admin/manage/users', ['translator'], function (translator) {
buttons: {
close: {
label: '[[global:close]]',
className: 'btn-link'
className: 'btn-link',
},
submit: {
label: '[[admin/manage/users:alerts.button-ban-x, ' + uids.length + ']]',
@@ -100,11 +99,11 @@ define('admin/manage/users', ['translator'], function (translator) {
data[cur.name] = cur.value;
return data;
}, {});
var until = formData.length ? (Date.now() + formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1)) : 0;
var until = formData.length ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
socket.emit('user.banUsers', { uids: uids, until: until, reason: formData.reason }, done('[[admin/manage/users:alerts.ban-success]]', '.ban', true));
}
}
}
},
},
},
});
});
});
@@ -266,7 +265,7 @@ define('admin/manage/users', ['translator'], function (translator) {
buttons: {
cancel: {
label: '[[admin/manage/users:alerts.button-cancel]]',
className: 'btn-link'
className: 'btn-link',
},
create: {
label: '[[admin/manage/users:alerts.button-create]]',
@@ -274,9 +273,9 @@ define('admin/manage/users', ['translator'], function (translator) {
callback: function () {
createUser.call(this);
return false;
}
}
}
},
},
},
});
});
});
@@ -298,11 +297,11 @@ define('admin/manage/users', ['translator'], function (translator) {
var user = {
username: username,
email: email,
password: password
password: password,
};
socket.emit('admin.user.createUser', user, function (err) {
if(err) {
if (err) {
return errorEl.translateHtml('[[admin/manage/users:alerts.error-x, ' + err.message + ']]').removeClass('hide');
}
@@ -323,12 +322,12 @@ define('admin/manage/users', ['translator'], function (translator) {
}
var $this = $(this);
var type = $this.attr('data-search-type');
var type = $this.attr('data-search-type');
timeoutId = setTimeout(function () {
$('.fa-spinner').removeClass('hidden');
socket.emit('admin.user.search', {searchBy: type, query: $this.val()}, function (err, data) {
socket.emit('admin.user.search', { searchBy: type, query: $this.val() }, function (err, data) {
if (err) {
return app.alertError(err.message);
}
@@ -361,7 +360,6 @@ define('admin/manage/users', ['translator'], function (translator) {
handleUserCreate();
handleInvite();
};
function handleInvite() {

View File

@@ -1,6 +1,5 @@
"use strict";
'use strict';
/*globals define*/
define('admin/modules/colorpicker', function () {
var colorpicker = {};
@@ -19,7 +18,7 @@ define('admin/modules/colorpicker', function () {
},
onShow: function (colpkr) {
$(colpkr).css('z-index', 1051);
}
},
});
});
};

View File

@@ -1,6 +1,5 @@
"use strict";
'use strict';
/*globals define, app, socket*/
define('admin/modules/instance', function () {
var instance = {};
@@ -11,7 +10,7 @@ define('admin/modules/instance', function () {
type: 'info',
title: 'Reloading... <i class="fa fa-spin fa-refresh"></i>',
message: 'NodeBB is reloading.',
timeout: 5000
timeout: 5000,
});
$(window).one('action:reconnected', function () {
@@ -20,7 +19,7 @@ define('admin/modules/instance', function () {
type: 'success',
title: '<i class="fa fa-check"></i> Success',
message: 'NodeBB has reloaded successfully.',
timeout: 5000
timeout: 5000,
});
if (typeof callback === 'function') {
@@ -37,7 +36,7 @@ define('admin/modules/instance', function () {
type: 'info',
title: 'Rebuilding... <i class="fa fa-spin fa-refresh"></i>',
message: 'NodeBB is rebuilding front-end assets (css, javascript, etc).',
timeout: 10000
timeout: 10000,
});
$(window).one('action:reconnected', function () {
@@ -46,7 +45,7 @@ define('admin/modules/instance', function () {
type: 'success',
title: '<i class="fa fa-check"></i> Success',
message: 'NodeBB has successfully restarted.',
timeout: 10000
timeout: 10000,
});
if (typeof callback === 'function') {
@@ -60,7 +59,7 @@ define('admin/modules/instance', function () {
type: 'info',
title: 'Build Complete!... <i class="fa fa-spin fa-refresh"></i>',
message: 'NodeBB is reloading.',
timeout: 10000
timeout: 10000,
});
});
};

View File

@@ -1,5 +1,5 @@
"use strict";
/* globals socket, app, define, ajaxify, config */
'use strict';
define('admin/modules/search', ['mousetrap'], function (mousetrap) {
var search = {};
@@ -73,7 +73,7 @@ define('admin/modules/search', ['mousetrap'], function (mousetrap) {
if (!selected.length) {
selected = menu.find('li.result > a').first().attr('href');
}
var href = selected ? selected : config.relative_path + '/search/' + input.val();
var href = selected || config.relative_path + '/search?in=titlesposts&term=' + input.val();
ajaxify.go(href.replace(/^\//, ''));
@@ -128,7 +128,7 @@ define('admin/modules/search', ['mousetrap'], function (mousetrap) {
menu.toggleClass('state-start-typing', len === 0);
menu.toggleClass('state-keep-typing', len > 0 && len < 3);
if (len >= 3) {
menu.prepend(find(dict, value));
@@ -140,7 +140,7 @@ define('admin/modules/search', ['mousetrap'], function (mousetrap) {
menu.find('.search-forum')
.not('.divider')
.find('a')
.attr('href', config.relative_path + '/search/' + value)
.attr('href', config.relative_path + '/search?in=titlesposts&term=' + value)
.find('strong')
.html(value);
} else {
@@ -150,4 +150,4 @@ define('admin/modules/search', ['mousetrap'], function (mousetrap) {
}
return search;
});
});

View File

@@ -1,13 +1,12 @@
"use strict";
'use strict';
/*globals define*/
define('admin/modules/selectable', ['jqueryui'], function (jqueryui) {
define('admin/modules/selectable', ['jqueryui'], function () {
var selectable = {};
selectable.enable = function (containerEl, targets) {
$(containerEl).selectable({
filter: targets
filter: targets,
});
};

View File

@@ -1,5 +1,5 @@
'use strict';
/*global define, app, socket, ajaxify */
define('admin/settings', ['uploader'], function (uploader) {
var Settings = {};
@@ -11,8 +11,8 @@ define('admin/settings', ['uploader'], function (uploader) {
Settings.populateTOC = function () {
$('.settings-header').each(function () {
var header = $(this).text(),
anchor = header.toLowerCase().replace(/ /g, '-').trim();
var header = $(this).text();
var anchor = header.toLowerCase().replace(/ /g, '-').trim();
$(this).prepend('<a name="' + anchor + '"></a>');
$('.section-content ul').append('<li><a href="#' + anchor + '">' + header + '</a></li>');
@@ -21,11 +21,14 @@ define('admin/settings', ['uploader'], function (uploader) {
Settings.prepare = function (callback) {
// Populate the fields on the page from the config
var fields = $('#content [data-field]'),
numFields = fields.length,
saveBtn = $('#save'),
revertBtn = $('#revert'),
x, key, inputType, field;
var fields = $('#content [data-field]');
var numFields = fields.length;
var saveBtn = $('#save');
var revertBtn = $('#revert');
var x;
var key;
var inputType;
var field;
// Handle unsaved changes
$(fields).on('change', function () {
@@ -33,7 +36,7 @@ define('admin/settings', ['uploader'], function (uploader) {
app.flags._unsaved = true;
});
for (x = 0; x < numFields; x++) {
for (x = 0; x < numFields; x += 1) {
field = fields.eq(x);
key = field.attr('data-field');
inputType = field.attr('type');
@@ -80,7 +83,7 @@ define('admin/settings', ['uploader'], function (uploader) {
timeout: 2500,
title: 'Changes Not Saved',
message: 'NodeBB encountered a problem saving your changes',
type: 'danger'
type: 'danger',
});
}
@@ -91,7 +94,7 @@ define('admin/settings', ['uploader'], function (uploader) {
timeout: 2500,
title: 'Changes Saved',
message: 'Your changes to the NodeBB configuration have been saved.',
type: 'success'
type: 'success',
});
$(window).trigger('action:admin.settingsSaved');
@@ -99,6 +102,7 @@ define('admin/settings', ['uploader'], function (uploader) {
});
handleUploads();
setupTagsInput();
$('#clear-sitemap-cache').off('click').on('click', function () {
socket.emit('admin.settings.clearSitemapCache', function () {
@@ -126,7 +130,7 @@ define('admin/settings', ['uploader'], function (uploader) {
route: uploadBtn.attr('data-route'),
params: {},
showHelp: uploadBtn.attr('data-help') ? uploadBtn.attr('data-help') === 1 : undefined,
accept: uploadBtn.attr('data-accept')
accept: uploadBtn.attr('data-accept'),
}, function (image) {
// need to move these into template, ex data-callback
if (ajaxify.currentPage === 'admin/general/sounds') {
@@ -139,6 +143,14 @@ define('admin/settings', ['uploader'], function (uploader) {
});
}
function setupTagsInput() {
$('[data-field-type="tagsinput"]').tagsinput({
confirmKeys: [13, 44],
trimValue: true,
});
app.flags._unsaved = false;
}
Settings.remove = function (key) {
socket.emit('admin.config.remove', key);
};
@@ -148,8 +160,9 @@ define('admin/settings', ['uploader'], function (uploader) {
fields.each(function () {
var field = $(this);
var key = field.attr('data-field'),
value, inputType;
var key = field.attr('data-field');
var value;
var inputType;
if (field.is('input')) {
inputType = field.attr('type');
@@ -178,7 +191,7 @@ define('admin/settings', ['uploader'], function (uploader) {
return callback(err);
}
for(var field in data) {
for (var field in data) {
if (data.hasOwnProperty(field)) {
app.config[field] = data[field];
}

View File

@@ -1,9 +1,8 @@
'use strict';
/* globals define */
define('admin/settings/cookies', [
'admin/modules/colorpicker'
'admin/modules/colorpicker',
], function (colorpicker) {
var Module = {};
@@ -22,4 +21,4 @@ define('admin/settings/cookies', [
};
return Module;
});
});

View File

@@ -1,9 +1,9 @@
"use strict";
/* global define, socket, app, ajaxify, ace */
'use strict';
define('admin/settings/email', ['admin/settings'], function (settings) {
var module = {},
emailEditor;
define('admin/settings/email', ['admin/settings'], function () {
var module = {};
var emailEditor;
module.init = function () {
configureEmailTester();
@@ -17,7 +17,7 @@ define('admin/settings/email', ['admin/settings'], function (settings) {
function configureEmailTester() {
$('button[data-action="email.test"]').off('click').on('click', function () {
socket.emit('admin.email.test', {template: $('#test-email').val()}, function (err) {
socket.emit('admin.email.test', { template: $('#test-email').val() }, function (err) {
if (err) {
return app.alertError(err.message);
}
@@ -30,10 +30,10 @@ define('admin/settings/email', ['admin/settings'], function (settings) {
function configureEmailEditor() {
$('#email-editor-selector').on('change', updateEmailEditor);
emailEditor = ace.edit("email-editor");
emailEditor = ace.edit('email-editor');
emailEditor.$blockScrolling = Infinity;
emailEditor.setTheme("ace/theme/twilight");
emailEditor.getSession().setMode("ace/mode/html");
emailEditor.setTheme('ace/theme/twilight');
emailEditor.getSession().setMode('ace/mode/html');
emailEditor.on('change', function () {
var emailPath = $('#email-editor-selector').val();

View File

@@ -1,7 +1,7 @@
"use strict";
/* global define, socket */
'use strict';
define('admin/settings/general', ['admin/settings'], function (Settings) {
define('admin/settings/general', ['admin/settings'], function () {
var Module = {};
Module.init = function () {

View File

@@ -1,7 +1,7 @@
"use strict";
/*global app, bootbox, templates, socket, config, RELATIVE_PATH*/
'use strict';
var ajaxify = ajaxify || {};
var ajaxify = window.ajaxify || {};
$(document).ready(function () {
var location = document.location || window.location;
@@ -25,11 +25,11 @@ $(document).ready(function () {
if (ev !== null && ev.state) {
if (ev.state.url === null && ev.state.returnPath !== undefined) {
window.history.replaceState({
url: ev.state.returnPath
url: ev.state.returnPath,
}, ev.state.returnPath, config.relative_path + '/' + ev.state.returnPath);
} else if (ev.state.url !== undefined) {
ajaxify.go(ev.state.url, function () {
$(window).trigger('action:popstate', {url: ev.state.url});
$(window).trigger('action:popstate', { url: ev.state.url });
}, true);
}
}
@@ -73,7 +73,7 @@ $(document).ready(function () {
// If any listeners alter url and set it to an empty string, abort the ajaxification
if (url === null) {
$(window).trigger('action:ajaxify.end', {url: url, tpl_url: ajaxify.data.template.name, title: ajaxify.data.title});
$(window).trigger('action:ajaxify.end', { url: url, tpl_url: ajaxify.data.template.name, title: ajaxify.data.title });
return false;
}
@@ -81,7 +81,6 @@ $(document).ready(function () {
$('#footer, #content').removeClass('hide').addClass('ajaxifying');
ajaxify.loadData(url, function (err, data) {
if (!err || (err && err.data && (parseInt(err.data.status, 10) !== 302 && parseInt(err.data.status, 10) !== 308))) {
ajaxify.updateHistory(url, quiet);
}
@@ -100,10 +99,11 @@ $(document).ready(function () {
};
ajaxify.handleRedirects = function (url) {
url = ajaxify.removeRelativePath(url.replace(/\/$/, '')).toLowerCase();
url = ajaxify.removeRelativePath(url.replace(/^\/|\/$/g, '')).toLowerCase();
var isClientToAdmin = url.startsWith('admin') && window.location.pathname.indexOf(RELATIVE_PATH + '/admin') !== 0;
var isAdminToClient = !url.startsWith('admin') && window.location.pathname.indexOf(RELATIVE_PATH + '/admin') === 0;
var uploadsOrApi = url.startsWith('uploads') || url.startsWith('api');
var uploadsOrApi = url.startsWith('assets/uploads') || url.startsWith('uploads') || url.startsWith('api');
if (isClientToAdmin || isAdminToClient || uploadsOrApi) {
window.open(RELATIVE_PATH + '/' + url, '_top');
return true;
@@ -116,7 +116,7 @@ $(document).ready(function () {
url = ajaxify.removeRelativePath(url.replace(/^\/|\/$/g, ''));
var payload = {
url: url
url: url,
};
$(window).trigger('action:ajaxify.start', payload);
@@ -128,7 +128,7 @@ $(document).ready(function () {
ajaxify.currentPage = url.split(/[?#]/)[0];
if (window.history && window.history.pushState) {
window.history[!quiet ? 'pushState' : 'replaceState']({
url: url
url: url,
}, url, RELATIVE_PATH + '/' + url);
}
};
@@ -158,7 +158,6 @@ $(document).ready(function () {
app.alertError('[[global:please_log_in]]');
app.previousUrl = url;
window.location.href = config.relative_path + '/login';
return;
} else if (status === 302 || status === 308) {
if (data.responseJSON && data.responseJSON.external) {
window.location.href = data.responseJSON.external;
@@ -195,18 +194,19 @@ $(document).ready(function () {
}
ajaxify.end = function (url, tpl_url) {
function done() {
if (--count === 0) {
$(window).trigger('action:ajaxify.end', {url: url, tpl_url: tpl_url, title: ajaxify.data.title});
}
}
var count = 2;
function done() {
count -= 1;
if (count === 0) {
$(window).trigger('action:ajaxify.end', { url: url, tpl_url: tpl_url, title: ajaxify.data.title });
}
}
ajaxify.loadScript(tpl_url, done);
ajaxify.widgets.render(tpl_url, url, done);
$(window).trigger('action:ajaxify.contentLoaded', {url: url, tpl: tpl_url});
$(window).trigger('action:ajaxify.contentLoaded', { url: url, tpl: tpl_url });
app.processPage();
@@ -243,7 +243,7 @@ $(document).ready(function () {
}
var data = {
tpl_url: tpl_url,
scripts: [location + tpl_url]
scripts: [location + tpl_url],
};
$(window).trigger('action:script.load', data);
@@ -285,13 +285,13 @@ $(document).ready(function () {
ajaxify.loadData = function (url, callback) {
url = ajaxify.removeRelativePath(url);
$(window).trigger('action:ajaxify.loadingData', {url: url});
$(window).trigger('action:ajaxify.loadingData', { url: url });
apiXHR = $.ajax({
url: RELATIVE_PATH + '/api/' + url,
cache: false,
headers: {
'X-Return-To': app.previousUrl
'X-Return-To': app.previousUrl,
},
success: function (data) {
if (!data) {
@@ -301,7 +301,7 @@ $(document).ready(function () {
ajaxify.data = data;
data.config = config;
$(window).trigger('action:ajaxify.dataLoaded', {url: url, data: data});
$(window).trigger('action:ajaxify.dataLoaded', { url: url, data: data });
callback(null, data);
},
@@ -311,9 +311,9 @@ $(document).ready(function () {
}
callback({
data: data,
textStatus: textStatus
textStatus: textStatus,
});
}
},
});
};
@@ -322,14 +322,14 @@ $(document).ready(function () {
callback(templates.cache[template]);
} else {
$.ajax({
url: config.relative_path + '/assets/templates/' + template + '.tpl' + '?' + config['cache-buster'],
url: config.relative_path + '/assets/templates/' + template + '.tpl?' + config['cache-buster'],
type: 'GET',
success: function (data) {
callback(data.toString());
},
error: function (error) {
throw new Error("Unable to load template: " + template + " (" + error.statusText + ")");
}
throw new Error('Unable to load template: ' + template + ' (' + error.statusText + ')');
},
});
}
};
@@ -344,6 +344,12 @@ $(document).ready(function () {
// Enhancing all anchors to ajaxify...
$(document.body).on('click', 'a', function (e) {
var _self = this;
if (this.target !== '' || (this.protocol !== 'http:' && this.protocol !== 'https:')) {
return;
}
var internalLink = utils.isInternalURI(this, window.location, RELATIVE_PATH);
var process = function () {
if (!e.ctrlKey && !e.shiftKey && !e.metaKey && e.which === 1) {
if (internalLink) {
@@ -352,35 +358,31 @@ $(document).ready(function () {
// Special handling for urls with hashes
if (window.location.pathname === this.pathname && this.hash.length) {
window.location.hash = this.hash;
} else {
if (ajaxify.go(pathname)) {
e.preventDefault();
}
} else if (ajaxify.go(pathname)) {
e.preventDefault();
}
} else if (window.location.pathname !== '/outgoing') {
if (config.openOutgoingLinksInNewTab && $.contains(contentEl, this)) {
window.open(this.href, '_blank');
e.preventDefault();
} else if (config.useOutgoingLinksPage) {
ajaxify.go('outgoing?url=' + encodeURIComponent(this.href));
e.preventDefault();
var safeUrls = config.outgoingLinksWhitelist.trim().split(/[\s,]+/g);
var href = this.href;
if (!safeUrls.some(function (url) { return href.indexOf(url) !== -1; })) {
ajaxify.go('outgoing?url=' + encodeURIComponent(href));
e.preventDefault();
}
}
}
}
};
if (this.target !== '' || (this.protocol !== 'http:' && this.protocol !== 'https:')) {
return;
}
var internalLink = utils.isInternalURI(this, window.location, RELATIVE_PATH);
if ($(this).attr('data-ajaxify') === 'false') {
if (!internalLink) {
return;
} else {
return e.preventDefault();
}
return e.preventDefault();
}
// Default behaviour for rss feeds
@@ -421,5 +423,4 @@ $(document).ready(function () {
templates.cache[$(this).attr('data-template')] = $('<div/>').html($(this).html()).text();
$(this).parent().remove();
});
});
});

View File

@@ -1,7 +1,7 @@
"use strict";
/*global templates, ajaxify, utils, bootbox, overrides, socket, config, Visibility*/
'use strict';
var app = app || {};
var app = window.app || {};
app.isFocused = true;
app.currentRoom = null;
@@ -17,7 +17,7 @@ app.cacheBuster = null;
app.cacheBuster = config['cache-buster'];
bootbox.setDefaults({
locale: config.userLang
locale: config.userLang,
});
app.load = function () {
@@ -69,7 +69,7 @@ app.cacheBuster = null;
clickfn: function () {
window.location.reload();
},
type: 'warning'
type: 'warning',
});
}
});
@@ -98,16 +98,16 @@ app.cacheBuster = null;
$.ajax(config.relative_path + '/logout', {
type: 'POST',
headers: {
'x-csrf-token': config.csrf_token
'x-csrf-token': config.csrf_token,
},
success: function () {
var payload = {
next: config.relative_path + '/'
next: config.relative_path + '/',
};
$(window).trigger('action:app.loggedOut', payload);
window.location.href = payload.next;
}
},
});
};
@@ -128,7 +128,7 @@ app.cacheBuster = null;
title: '[[global:alert.success]]',
message: message,
type: 'success',
timeout: timeout ? timeout : 5000
timeout: timeout || 5000,
});
};
@@ -143,7 +143,7 @@ app.cacheBuster = null;
title: '[[global:alert.error]]',
message: message,
type: 'danger',
timeout: timeout ? timeout : 10000
timeout: timeout || 10000,
});
};
@@ -163,7 +163,7 @@ app.cacheBuster = null;
closeButton: false,
callback: function () {
window.location.reload();
}
},
});
});
});
@@ -175,7 +175,7 @@ app.cacheBuster = null;
var previousRoom = app.currentRoom;
app.currentRoom = room;
socket.emit('meta.rooms.enter', {
enter: room
enter: room,
}, function (err) {
if (err) {
app.currentRoom = previousRoom;
@@ -213,7 +213,7 @@ app.cacheBuster = null;
if (!utils.isTouchDevice()) {
$(this).tooltip({
placement: placement || $(this).attr('title-placement') || 'top',
title: $(this).attr('title')
title: $(this).attr('title'),
});
}
});
@@ -222,8 +222,8 @@ app.cacheBuster = null;
app.createStatusTooltips = function () {
if (!utils.isTouchDevice()) {
$('body').tooltip({
selector:'.fa-circle.status',
placement: 'top'
selector: '.fa-circle.status',
placement: 'top',
});
}
};
@@ -262,36 +262,36 @@ app.cacheBuster = null;
login: {
format: 'alert',
title: '[[global:welcome_back]] ' + app.user.username + '!',
message: '[[global:you_have_successfully_logged_in]]'
message: '[[global:you_have_successfully_logged_in]]',
},
banned: {
format: 'modal',
title: '[[error:user-banned]]',
message: '[[error:user-banned-reason, ' + utils.params().banned + ']]'
}
message: '[[error:user-banned-reason, ' + utils.params().banned + ']]',
},
};
function showAlert(type) {
switch (messages[type].format) {
case 'alert':
app.alert({
type: 'success',
title: messages[type].title,
message: messages[type].message,
timeout: 5000
});
break;
case 'alert':
app.alert({
type: 'success',
title: messages[type].title,
message: messages[type].message,
timeout: 5000,
});
break;
case 'modal':
require(['translator'], function (translator) {
translator.translate(messages[type].message, function (translated) {
bootbox.alert({
title: messages[type].title,
message: translated
});
case 'modal':
require(['translator'], function (translator) {
translator.translate(messages[type].message, function (translated) {
bootbox.alert({
title: messages[type].title,
message: translated,
});
});
break;
});
break;
}
}
@@ -325,7 +325,7 @@ app.cacheBuster = null;
if (chat.modalExists(roomId)) {
loadAndCenter(chat.getModal(roomId));
} else {
socket.emit('modules.chats.loadRoom', {roomId: roomId, uid: uid || app.user.uid}, function (err, roomData) {
socket.emit('modules.chats.loadRoom', { roomId: roomId, uid: uid || app.user.uid }, function (err, roomData) {
if (err) {
return app.alertError(err.message);
}
@@ -349,7 +349,7 @@ app.cacheBuster = null;
return app.alertError('[[error:cant-chat-with-yourself]]');
}
socket.emit('modules.chats.newRoom', {touid: touid}, function (err, roomId) {
socket.emit('modules.chats.newRoom', { touid: touid }, function (err, roomId) {
if (err) {
return app.alertError(err.message);
}
@@ -365,10 +365,10 @@ app.cacheBuster = null;
};
var titleObj = {
active: false,
interval: undefined,
titles: []
};
active: false,
interval: undefined,
titles: [],
};
app.alternatingTitle = function (title) {
if (typeof title !== 'string') {
@@ -424,7 +424,7 @@ app.cacheBuster = null;
app.toggleNavbar = function (state) {
var navbarEl = $('.navbar');
if (navbarEl) {
navbarEl.toggleClass('hidden', !!!state);
navbarEl.toggleClass('hidden', !state);
}
};
@@ -438,7 +438,7 @@ app.cacheBuster = null;
$(this).tooltip({
placement: 'bottom',
trigger: 'hover',
title: $(this).attr('title')
title: $(this).attr('title'),
});
}
});
@@ -447,7 +447,7 @@ app.cacheBuster = null;
$('#search-form').parent().tooltip({
placement: 'bottom',
trigger: 'hover',
title: $('#search-button i').attr('title')
title: $('#search-button i').attr('title'),
});
}
@@ -455,15 +455,15 @@ app.cacheBuster = null;
$('#user_dropdown').tooltip({
placement: 'bottom',
trigger: 'hover',
title: $('#user_dropdown').attr('title')
title: $('#user_dropdown').attr('title'),
});
}
}
app.handleSearch = function () {
var searchButton = $("#search-button"),
searchFields = $("#search-fields"),
searchInput = $('#search-fields input');
var searchButton = $('#search-button');
var searchFields = $('#search-fields');
var searchInput = $('#search-fields input');
$('#search-form .advanced-search-link').on('mousedown', function () {
ajaxify.go('/search');
@@ -480,8 +480,8 @@ app.cacheBuster = null;
searchButton.on('click', function (e) {
if (!config.loggedIn && !config.allowGuestSearching) {
app.alert({
message:'[[error:search-requires-login]]',
timeout: 3000
message: '[[error:search-requires-login]]',
timeout: 3000,
});
ajaxify.go('login');
return false;
@@ -506,8 +506,8 @@ app.cacheBuster = null;
};
app.prepareSearch = function () {
$("#search-fields").removeClass('hidden');
$("#search-button").addClass('hidden');
$('#search-fields').removeClass('hidden');
$('#search-button').addClass('hidden');
$('#search-fields input').focus();
};
@@ -515,7 +515,7 @@ app.cacheBuster = null;
$('[component="header/usercontrol"] [data-status]').off('click').on('click', function (e) {
var status = $(this).attr('data-status');
socket.emit('user.setStatus', status, function (err) {
if(err) {
if (err) {
return app.alertError(err.message);
}
$('[data-uid="' + app.user.uid + '"] [component="user/status"], [component="header/profilelink"] [component="user/status"]')
@@ -546,7 +546,7 @@ app.cacheBuster = null;
app.newTopic = function (cid, tags) {
$(window).trigger('action:composer.topic.new', {
cid: cid || ajaxify.data.cid || 0,
tags: tags || (ajaxify.data.tag ? [ajaxify.data.tag] : [])
tags: tags || (ajaxify.data.tag ? [ajaxify.data.tag] : []),
});
};
@@ -557,7 +557,7 @@ app.cacheBuster = null;
var scriptEl = document.createElement('script');
scriptEl.type = 'text/javascript';
scriptEl.src = config.relative_path + '/assets/vendor/jquery/js/jquery-ui.js' + '?' + config['cache-buster'];
scriptEl.src = config.relative_path + '/assets/vendor/jquery/js/jquery-ui.js?' + config['cache-buster'];
scriptEl.onload = callback;
document.head.appendChild(scriptEl);
};
@@ -569,7 +569,7 @@ app.cacheBuster = null;
var msg = {
alert_id: 'email_confirm',
type: 'warning',
timeout: 0
timeout: 0,
};
if (!app.user.email) {
@@ -656,6 +656,5 @@ app.cacheBuster = null;
});
});
});
};
}());

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define */
define('forum/account/best', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
var Best = {};

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define */
define('forum/account/bookmarks', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
var Bookmarks = {};

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define */
define('forum/account/downvoted', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
var Downvoted = {};

View File

@@ -1,12 +1,10 @@
'use strict';
/* globals define, ajaxify, socket, app, config, templates, bootbox */
define('forum/account/edit', ['forum/account/header', 'translator', 'components', 'pictureCropper'], function (header, translator, components, pictureCropper) {
var AccountEdit = {};
AccountEdit.init = function () {
header.init();
$('#submitBtn').on('click', updateProfile);
@@ -16,7 +14,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
changeMonth: true,
changeYear: true,
yearRange: '1900:-5y',
defaultDate: '-13y'
defaultDate: '-13y',
});
});
@@ -36,7 +34,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
location: $('#inputLocation').val(),
groupTitle: $('#groupTitle').val(),
signature: $('#inputSignature').val(),
aboutme: $('#inputAboutMe').val()
aboutme: $('#inputAboutMe').val(),
};
$(window).trigger('action:profile.update', userData);
@@ -71,10 +69,9 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
}
function handleImageChange() {
$('#changePictureBtn').on('click', function () {
socket.emit('user.getProfilePictures', {
uid: ajaxify.data.uid
uid: ajaxify.data.uid,
}, function (err, pictures) {
if (err) {
return app.alertError(err.message);
@@ -88,7 +85,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
templates.parse('partials/modals/change_picture_modal', {
pictures: pictures,
uploaded: uploaded,
allowProfileImageUploads: ajaxify.data.allowProfileImageUploads
allowProfileImageUploads: ajaxify.data.allowProfileImageUploads,
}, function (html) {
translator.translate(html, function (html) {
var modal = bootbox.dialog({
@@ -100,13 +97,13 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
close: {
label: '[[global:close]]',
callback: onCloseModal,
className: 'btn-link'
className: 'btn-link',
},
update: {
label: '[[global:save_changes]]',
callback: saveSelection
}
}
callback: saveSelection,
},
},
});
modal.on('shown.bs.modal', updateImages);
@@ -171,15 +168,14 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
if ($('#confirm-username').val() !== app.user.username) {
app.alertError('[[error:invalid-username]]');
return false;
} else {
socket.emit('user.deleteAccount', {}, function (err) {
if (err) {
return app.alertError(err.message);
}
window.location.href = config.relative_path + '/';
});
}
socket.emit('user.deleteAccount', {}, function (err) {
if (err) {
return app.alertError(err.message);
}
window.location.href = config.relative_path + '/';
});
});
modal.on('shown.bs.modal', function () {
@@ -192,7 +188,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
function handleImageUpload(modal) {
function onUploadComplete(urlOnServer) {
urlOnServer = urlOnServer + '?' + Date.now();
urlOnServer = config.relative_path + urlOnServer + '?' + Date.now();
updateHeader(urlOnServer);
@@ -227,7 +223,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
imageDimension: ajaxify.data.profileImageDimension,
title: '[[user:upload_picture]]',
description: '[[user:upload_a_picture]]',
accept: '.png,.jpg,.bmp'
accept: '.png,.jpg,.bmp',
}, function (url) {
onUploadComplete(url);
});
@@ -245,22 +241,29 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
uploadModal.find('.upload-btn').on('click', function () {
var url = uploadModal.find('#uploadFromUrl').val();
if (!url) {
return;
return false;
}
uploadModal.modal('hide');
pictureCropper.handleImageCrop({
socket.emit('user.uploadProfileImageFromUrl', {
uid: ajaxify.data.uid,
url: url,
socketMethod: 'user.uploadCroppedPicture',
aspectRatio: '1 / 1',
allowSkippingCrop: false,
restrictImageDimension: true,
imageDimension: ajaxify.data.profileImageDimension,
paramName: 'uid',
paramValue: ajaxify.data.theirid,
}, onUploadComplete);
}, function (err, url) {
if (err) {
return app.alertError(err);
}
uploadModal.modal('hide');
pictureCropper.handleImageCrop({
url: url,
socketMethod: 'user.uploadCroppedPicture',
aspectRatio: '1 / 1',
allowSkippingCrop: false,
restrictImageDimension: true,
imageDimension: ajaxify.data.profileImageDimension,
paramName: 'uid',
paramValue: ajaxify.data.theirid,
}, onUploadComplete);
});
return false;
});
});
@@ -271,7 +274,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
modal.find('[data-action="remove-uploaded"]').on('click', function () {
socket.emit('user.removeUploadedPicture', {
uid: ajaxify.data.theirid
uid: ajaxify.data.theirid,
}, function (err) {
modal.modal('hide');
if (err) {
@@ -298,7 +301,7 @@ define('forum/account/edit', ['forum/account/header', 'translator', 'components'
function changeUserPicture(type, callback) {
socket.emit('user.changePicture', {
type: type,
uid: ajaxify.data.theirid
uid: ajaxify.data.theirid,
}, callback);
}

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define, ajaxify, socket, app */
define('forum/account/edit/email', ['forum/account/header'], function (header) {
var AccountEditEmail = {};
@@ -12,7 +11,7 @@ define('forum/account/edit/email', ['forum/account/header'], function (header) {
var userData = {
uid: $('#inputUID').val(),
email: $('#inputNewEmail').val(),
password: $('#inputCurrentPassword').val()
password: $('#inputCurrentPassword').val(),
};
if (!userData.email) {

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define, ajaxify, socket, app, utils */
define('forum/account/edit/password', ['forum/account/header', 'translator'], function (header, translator) {
var AccountEditPassword = {};
@@ -64,9 +63,9 @@ define('forum/account/edit/password', ['forum/account/header', 'translator'], fu
if ((passwordvalid && passwordsmatch) || app.user.isAdmin) {
btn.addClass('disabled').find('i').removeClass('hide');
socket.emit('user.changePassword', {
'currentPassword': currentPassword.val(),
'newPassword': password.val(),
'uid': ajaxify.data.theirid
currentPassword: currentPassword.val(),
newPassword: password.val(),
uid: ajaxify.data.theirid,
}, function (err) {
btn.removeClass('disabled').find('i').addClass('hide');
currentPassword.val('');
@@ -80,8 +79,8 @@ define('forum/account/edit/password', ['forum/account/header', 'translator'], fu
onPasswordConfirmChanged();
return app.alertError(err.message);
}
ajaxify.go('user/' + ajaxify.data.userslug);
app.alertSuccess('[[user:change_password_success]]');
window.location.href = config.relative_path + '/login';
});
} else {
if (!passwordsmatch) {

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define, ajaxify, socket, app, utils, config */
define('forum/account/edit/username', ['forum/account/header'], function (header) {
var AccountEditUsername = {};
@@ -12,7 +11,7 @@ define('forum/account/edit/username', ['forum/account/header'], function (header
var userData = {
uid: $('#inputUID').val(),
username: $('#inputNewUsername').val(),
password: $('#inputCurrentPassword').val()
password: $('#inputCurrentPassword').val(),
};
if (!userData.username) {

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define */
define('forum/account/followers', ['forum/account/header'], function (header) {
var Followers = {};

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define */
define('forum/account/following', ['forum/account/header'], function (header) {
var Following = {};

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals ajaxify, define, app, socket, utils */
define('forum/account/groups', ['forum/account/header'], function (header) {
var AccountTopics = {};

View File

@@ -1,11 +1,11 @@
'use strict';
/* globals define, app, config, ajaxify, socket, bootbox, templates */
define('forum/account/header', [
'coverPhoto',
'pictureCropper',
'components',
'translator'
'translator',
], function (coverPhoto, pictureCropper, components, translator) {
var AccountHeader = {};
var isAdminOrSelfOrGlobalMod;
@@ -76,7 +76,7 @@ define('forum/account/header', [
socket.emit('user.updateCover', {
uid: ajaxify.data.uid,
imageData: imageData,
position: position
position: position,
}, callback);
},
function () {
@@ -88,7 +88,7 @@ define('forum/account/header', [
restrictImageDimension: false,
paramName: 'uid',
paramValue: ajaxify.data.theirid,
accept: '.png,.jpg,.bmp'
accept: '.png,.jpg,.bmp',
}, function (imageUrlOnServer) {
components.get('account/cover').css('background-image', 'url(' + imageUrlOnServer + '?' + config['cache-buster'] + ')');
});
@@ -99,7 +99,7 @@ define('forum/account/header', [
function toggleFollow(type) {
socket.emit('user.' + type, {
uid: ajaxify.data.uid
uid: ajaxify.data.uid,
}, function (err) {
if (err) {
return app.alertError(err.message);
@@ -122,7 +122,7 @@ define('forum/account/header', [
buttons: {
close: {
label: '[[global:close]]',
className: 'btn-link'
className: 'btn-link',
},
submit: {
label: '[[user:ban_account]]',
@@ -131,21 +131,21 @@ define('forum/account/header', [
data[cur.name] = cur.value;
return data;
}, {});
var until = parseInt(formData.length, 10) ? (Date.now() + formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1)) : 0;
var until = parseInt(formData.length, 10) ? (Date.now() + (formData.length * 1000 * 60 * 60 * (parseInt(formData.unit, 10) ? 24 : 1))) : 0;
socket.emit('user.banUsers', {
uids: [ajaxify.data.theirid],
until: until,
reason: formData.reason || ''
reason: formData.reason || '',
}, function (err) {
if (err) {
return app.alertError(err.message);
}
ajaxify.refresh();
});
}
}
}
},
},
},
});
});
}
@@ -185,7 +185,7 @@ define('forum/account/header', [
}
socket.emit('user.removeCover', {
uid: ajaxify.data.uid
uid: ajaxify.data.uid,
}, function (err) {
if (!err) {
ajaxify.refresh();

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define, socket, ajaxify, app */
define('forum/account/info', ['forum/account/header', 'components'], function (header, components) {
var Info = {};
@@ -14,7 +13,7 @@ define('forum/account/info', ['forum/account/header', 'components'], function (h
function handleModerationNote() {
$('[component="account/save-moderation-note"]').on('click', function () {
var note = $('[component="account/moderation-note"]').val();
socket.emit('user.setModerationNote', {uid: ajaxify.data.uid, note: note}, function (err) {
socket.emit('user.setModerationNote', { uid: ajaxify.data.uid, note: note }, function (err) {
if (err) {
return app.alertError(err.message);
}
@@ -35,8 +34,8 @@ define('forum/account/info', ['forum/account/header', 'components'], function (h
url: config.relative_path + '/api/user/' + ajaxify.data.userslug + '/session/' + uuid,
method: 'delete',
headers: {
'x-csrf-token': config.csrf_token
}
'x-csrf-token': config.csrf_token,
},
}).done(function () {
parentEl.remove();
}).fail(function (err) {

View File

@@ -1,10 +1,10 @@
'use strict';
/* globals define, app, socket, utils, config, ajaxify */
define('forum/account/posts', ['forum/account/header', 'forum/infinitescroll'], function (header, infinitescroll) {
var AccountPosts = {};
var method, template;
var method;
var template;
AccountPosts.init = function () {
header.init();
@@ -29,7 +29,7 @@ define('forum/account/posts', ['forum/account/header', 'forum/infinitescroll'],
infinitescroll.loadMore(method, {
uid: ajaxify.data.theirid,
after: $('[component="posts"]').attr('data-nextstart')
after: $('[component="posts"]').attr('data-nextstart'),
}, function (data, done) {
if (data.posts && data.posts.length) {
onPostsLoaded(data.posts, done);
@@ -41,7 +41,7 @@ define('forum/account/posts', ['forum/account/header', 'forum/infinitescroll'],
}
function onPostsLoaded(posts, callback) {
app.parseAndTranslate(template, 'posts', {posts: posts}, function (html) {
app.parseAndTranslate(template, 'posts', { posts: posts }, function (html) {
$('[component="posts"]').append(html);
html.find('img:not(.not-responsive)').addClass('img-responsive');
html.find('.timeago').timeago();

View File

@@ -1,13 +1,11 @@
'use strict';
/* globals define, ajaxify, app, socket, bootbox */
define('forum/account/profile', [
'forum/account/header',
'forum/infinitescroll',
'translator',
'components'
], function (header, infinitescroll, translator) {
'components',
], function (header, infinitescroll) {
var Account = {};
var theirid;
@@ -22,10 +20,10 @@ define('forum/account/profile', [
socket.removeListener('event:user_status_change', onUserStatusChange);
socket.on('event:user_status_change', onUserStatusChange);
if (!config.usePagination) {
infinitescroll.init(loadMorePosts);
}
infinitescroll.init(loadMorePosts);
}
};
function processPage() {
@@ -49,7 +47,7 @@ define('forum/account/profile', [
infinitescroll.loadMore('posts.loadMoreUserPosts', {
after: $('[component="posts"]').attr('data-nextstart'),
uid: theirid
uid: theirid,
}, function (data, done) {
if (data.posts && data.posts.length) {
onPostsLoaded(data.posts, done);
@@ -70,8 +68,7 @@ define('forum/account/profile', [
return callback();
}
app.parseAndTranslate('account/profile', 'posts', {posts: posts}, function (html) {
app.parseAndTranslate('account/profile', 'posts', { posts: posts }, function (html) {
$('[component="posts"]').append(html);
html.find('.timeago').timeago();

View File

@@ -1,10 +1,15 @@
'use strict';
/*global define, socket, app, ajaxify, config*/
define('forum/account/settings', ['forum/account/header', 'components', 'sounds'], function (header, components, sounds) {
var AccountSettings = {};
$(window).on('action:ajaxify.start', function () {
if (ajaxify.data.template.name === 'account/settings' && $('#bootswatchSkin').val() !== config.bootswatchSkin) {
changePageSkin(config.bootswatchSkin);
}
});
AccountSettings.init = function () {
header.init();
@@ -25,10 +30,7 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
});
$('#bootswatchSkin').on('change', function () {
var css = $('#bootswatchCSS');
var val = $(this).val() === 'default' ? config['theme:src'] : '//maxcdn.bootstrapcdn.com/bootswatch/latest/' + $(this).val() + '/bootstrap.min.css';
css.attr('href', val);
changePageSkin($(this).val());
});
$('[data-property="homePageRoute"]').on('change', toggleCustomRoute);
@@ -45,6 +47,29 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
components.get('user/sessions').find('.timeago').timeago();
};
function changePageSkin(skinName) {
var css = $('#bootswatchCSS');
if (skinName === 'noskin' || (skinName === 'default' && config.defaultBootswatchSkin === 'noskin')) {
css.remove();
} else {
if (skinName === 'default') {
skinName = config.defaultBootswatchSkin;
}
var cssSource = '//maxcdn.bootstrapcdn.com/bootswatch/latest/' + skinName + '/bootstrap.min.css';
if (css.length) {
css.attr('href', cssSource);
} else {
css = $('<link id="bootswatchCSS" href="' + cssSource + '" rel="stylesheet" media="screen">');
$('head').append(css);
}
}
var currentSkinClassName = $('body').attr('class').split(/\s+/).filter(function (className) {
return className.startsWith('skin-');
});
$('body').removeClass(currentSkinClassName.join(' ')).addClass('skin-' + skinName);
}
function loadSettings() {
var settings = {};
@@ -57,13 +82,13 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
}
switch (input.attr('type')) {
case 'text':
case 'textarea':
settings[setting] = input.val();
break;
case 'checkbox':
settings[setting] = input.is(':checked') ? 1 : 0;
break;
case 'text':
case 'textarea':
settings[setting] = input.val();
break;
case 'checkbox':
settings[setting] = input.is(':checked') ? 1 : 0;
break;
}
});
@@ -71,7 +96,7 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
}
function saveSettings(settings) {
socket.emit('user.saveSettings', {uid: ajaxify.data.theirid, settings: settings}, function (err, newSettings) {
socket.emit('user.saveSettings', { uid: ajaxify.data.theirid, settings: settings }, function (err, newSettings) {
if (err) {
return app.alertError(err.message);
}
@@ -99,7 +124,7 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'
timeout: 5000,
clickfn: function () {
ajaxify.refresh();
}
},
});
}
});

View File

@@ -1,10 +1,9 @@
'use strict';
/* globals define, app, socket, utils, config, ajaxify */
define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'], function (header, infinitescroll) {
var AccountTopics = {};
var template, set;
var set;
AccountTopics.init = function () {
header.init();
@@ -13,7 +12,6 @@ define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'],
};
AccountTopics.handleInfiniteScroll = function (_template, _set) {
template = _template;
set = _set;
if (!config.usePagination) {
@@ -28,7 +26,7 @@ define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'],
infinitescroll.loadMore('topics.loadMoreFromSet', {
set: set,
after: $('[component="category"]').attr('data-nextstart')
after: $('[component="category"]').attr('data-nextstart'),
}, function (data, done) {
if (data.topics && data.topics.length) {
onTopicsLoaded(data.topics, done);
@@ -41,12 +39,12 @@ define('forum/account/topics', ['forum/account/header', 'forum/infinitescroll'],
}
function onTopicsLoaded(topics, callback) {
app.parseAndTranslate('account/topics', 'topics', {topics: topics}, function (html) {
app.parseAndTranslate('account/topics', 'topics', { topics: topics }, function (html) {
$('[component="category"]').append(html);
html.find('.timeago').timeago();
app.createUserTooltips();
utils.makeNumbersHumanReadable(html.find('.human-readable-number'));
$(window).trigger('action:topics.loaded', {topics: topics});
$(window).trigger('action:topics.loaded', { topics: topics });
callback();
});
}

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define */
define('forum/account/upvoted', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
var Upvoted = {};

View File

@@ -1,6 +1,6 @@
'use strict';
/* globals define, app, socket, utils */
define('forum/account/watched', ['forum/account/header', 'forum/account/topics'], function (header, topics) {
var AccountWatched = {};

View File

@@ -1,6 +1,5 @@
'use strict';
/* globals define, socket, app, templates, ajaxify*/
define('forum/categories', ['components', 'translator'], function (components, translator) {
var categories = {};
@@ -18,7 +17,7 @@ define('forum/categories', ['components', 'translator'], function (components, t
socket.on('event:new_post', categories.onNewPost);
$('.category-header').tooltip({
placement: 'bottom'
placement: 'bottom',
});
};
@@ -36,11 +35,10 @@ define('forum/categories', ['components', 'translator'], function (components, t
}
var recentPosts = category.find('[component="category/posts"]');
var insertBefore = recentPosts.first();
parseAndTranslate([post], function (html) {
html.hide();
if(recentPosts.length === 0) {
if (recentPosts.length === 0) {
html.appendTo(category);
} else {
html.insertBefore(recentPosts.first());
@@ -55,12 +53,12 @@ define('forum/categories', ['components', 'translator'], function (components, t
recentPosts.last().remove();
}
$(window).trigger('action:posts.loaded', {posts: [post]});
$(window).trigger('action:posts.loaded', { posts: [post] });
});
}
function parseAndTranslate(posts, callback) {
templates.parse('categories', '(categories.)?posts', {categories: {posts: posts}}, function (html) {
templates.parse('categories', '(categories.)?posts', { categories: { posts: posts } }, function (html) {
translator.translate(html, function (translatedHTML) {
translatedHTML = $(translatedHTML);
translatedHTML.find('.post-content img:not(.not-responsive)').addClass('img-responsive');

Some files were not shown because too many files have changed in this diff Show More