mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-06-27 07:28:18 +02:00
Merge commit '449352d8996b4c98be67052fbb5b68fdc65cd0f2' into v1.x.x
This commit is contained in:
@@ -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
128
.eslintrc
Normal 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"
|
||||
}
|
||||
}
|
||||
111
.eslintrc.json
111
.eslintrc.json
@@ -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"
|
||||
}
|
||||
}
|
||||
15
.github/CONTRIBUTING.md
vendored
15
.github/CONTRIBUTING.md
vendored
@@ -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
1
.gitignore
vendored
@@ -57,3 +57,4 @@ tx.exe
|
||||
coverage
|
||||
|
||||
build
|
||||
*.log
|
||||
|
||||
54
Gruntfile.js
54
Gruntfile.js
@@ -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
21
app.js
@@ -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);
|
||||
|
||||
12
bcrypt.js
12
bcrypt.js
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
80
loader.js
80
loader.js
@@ -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');
|
||||
}
|
||||
});
|
||||
|
||||
17
package.json
17
package.json
@@ -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
58
public/.eslintrc
Normal 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
84
public/.jshintrc
Normal 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
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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!"
|
||||
}
|
||||
@@ -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><head></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><head></code> sezione del markup del tuo forum",
|
||||
"custom-header.enable": "Abilita l'Intestazione Personalizzata"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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.",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)",
|
||||
|
||||
@@ -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": "Ваша адреса е-поште још увек није оверена, кликните овде да би сте то учинили.",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"save_changes": "Сачувај измене",
|
||||
"save": "Сачувај",
|
||||
"close": "Затвори",
|
||||
"pagination": "Обележавање страна",
|
||||
"pagination": "Нумерисање страница",
|
||||
"pagination.out_of": "%1 од %2",
|
||||
"pagination.enter_index": "Унесите индекс",
|
||||
"header.admin": "Админ",
|
||||
|
||||
@@ -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": "Пријавите се да бисте одговорили",
|
||||
|
||||
@@ -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": "Репродукуј звук приликом примања обавештења",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "邀请注册",
|
||||
|
||||
@@ -272,4 +272,8 @@ body {
|
||||
border: 1px dashed @brand-success;
|
||||
background: lighten(@brand-success, 10%);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
form small {
|
||||
color: @gray-light;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
public/src/admin/.eslintrc
Normal file
8
public/src/admin/.eslintrc
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"globals": {
|
||||
"ace": true,
|
||||
"Sortable": true,
|
||||
"Slideout": true,
|
||||
"NProgress": true
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
});
|
||||
});
|
||||
}
|
||||
}());
|
||||
}());
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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> </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);
|
||||
|
||||
@@ -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>' +
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";
|
||||
/*global define*/
|
||||
'use strict';
|
||||
|
||||
|
||||
define('admin/general/languages', ['admin/settings'], function (Settings) {
|
||||
var Languages = {};
|
||||
|
||||
@@ -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' : '');
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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(', ')
|
||||
),
|
||||
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;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
}());
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define */
|
||||
|
||||
define('forum/account/best', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
|
||||
var Best = {};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define */
|
||||
|
||||
define('forum/account/bookmarks', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
|
||||
var Bookmarks = {};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define */
|
||||
|
||||
define('forum/account/downvoted', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
|
||||
var Downvoted = {};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define */
|
||||
|
||||
define('forum/account/followers', ['forum/account/header'], function (header) {
|
||||
var Followers = {};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define */
|
||||
|
||||
define('forum/account/following', ['forum/account/header'], function (header) {
|
||||
var Following = {};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
/* globals ajaxify, define, app, socket, utils */
|
||||
|
||||
define('forum/account/groups', ['forum/account/header'], function (header) {
|
||||
var AccountTopics = {};
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
/* globals define */
|
||||
|
||||
define('forum/account/upvoted', ['forum/account/header', 'forum/account/posts'], function (header, posts) {
|
||||
var Upvoted = {};
|
||||
|
||||
@@ -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 = {};
|
||||
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user