mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-06-26 03:50:07 +02:00
Merge commit 'cdbe535e13557d57b37b84ad59c449e4fbbada04' into weekly
This commit is contained in:
46
.tx/config
46
.tx/config
@@ -919,4 +919,50 @@ trans.tr = public/language/tr/groups.json
|
||||
trans.vi = public/language/vi/groups.json
|
||||
trans.zh_CN = public/language/zh_CN/groups.json
|
||||
trans.zh_TW = public/language/zh_TW/groups.json
|
||||
type = KEYVALUEJSON
|
||||
|
||||
[nodebb.uploads]
|
||||
file_filter = public/language/<lang>/uploads.json
|
||||
source_file = public/language/en_GB/uploads.json
|
||||
source_lang = en_GB
|
||||
trans.ar = public/language/ar/uploads.json
|
||||
trans.bn = public/language/bn/uploads.json
|
||||
trans.bg = public/language/bg/uploads.json
|
||||
trans.cs = public/language/cs/uploads.json
|
||||
trans.da = public/language/da/uploads.json
|
||||
trans.de = public/language/de/uploads.json
|
||||
trans.el = public/language/el/uploads.json
|
||||
trans.en_US = public/language/en_US/uploads.json
|
||||
trans.en@pirate = public/language/en@pirate/uploads.json
|
||||
trans.es = public/language/es/uploads.json
|
||||
trans.et = public/language/et/uploads.json
|
||||
trans.fa_IR = public/language/fa_IR/uploads.json
|
||||
trans.fi = public/language/fi/uploads.json
|
||||
trans.fr = public/language/fr/uploads.json
|
||||
trans.gl = public/language/gl/uploads.json
|
||||
trans.he = public/language/he/uploads.json
|
||||
trans.hu = public/language/hu/uploads.json
|
||||
trans.id = public/language/id/uploads.json
|
||||
trans.it = public/language/it/uploads.json
|
||||
trans.ja = public/language/ja/uploads.json
|
||||
trans.ko = public/language/ko/uploads.json
|
||||
trans.lt = public/language/lt/uploads.json
|
||||
trans.ms = public/language/ms/uploads.json
|
||||
trans.nb = public/language/nb/uploads.json
|
||||
trans.nl = public/language/nl/uploads.json
|
||||
trans.pl = public/language/pl/uploads.json
|
||||
trans.pt_BR = public/language/pt_BR/uploads.json
|
||||
trans.ru = public/language/ru/uploads.json
|
||||
trans.ro = public/language/ro/uploads.json
|
||||
trans.rw = public/language/rw/uploads.json
|
||||
trans.sc = public/language/sc/uploads.json
|
||||
trans.sk = public/language/sk/uploads.json
|
||||
trans.sl = public/language/sl/uploads.json
|
||||
trans.sr = public/language/sr/uploads.json
|
||||
trans.sv = public/language/sv/uploads.json
|
||||
trans.th = public/language/th/uploads.json
|
||||
trans.tr = public/language/tr/uploads.json
|
||||
trans.vi = public/language/vi/uploads.json
|
||||
trans.zh_CN = public/language/zh_CN/uploads.json
|
||||
trans.zh_TW = public/language/zh_TW/uploads.json
|
||||
type = KEYVALUEJSON
|
||||
22
Gruntfile.js
22
Gruntfile.js
@@ -57,19 +57,35 @@ module.exports = function(grunt) {
|
||||
grunt.initConfig({
|
||||
watch: {
|
||||
lessUpdated_Client: {
|
||||
files: ['public/*.less', 'node_modules/nodebb-*/*.less', 'node_modules/nodebb-*/*/*.less', 'node_modules/nodebb-*/*/*/*.less', 'node_modules/nodebb-*/*/*/*/*.less']
|
||||
files: [
|
||||
'public/*.less',
|
||||
'node_modules/nodebb-*/*.less', 'node_modules/nodebb-*/**/*.less',
|
||||
'!node_modules/nodebb-*/node_modules/**',
|
||||
'!node_modules/nodebb-*/.git/**'
|
||||
]
|
||||
},
|
||||
lessUpdated_Admin: {
|
||||
files: ['public/**/*.less']
|
||||
},
|
||||
clientUpdated: {
|
||||
files: ['public/src/**/*.js', 'node_modules/nodebb-*/*.js', 'node_modules/nodebb-*/*/*.js', 'node_modules/nodebb-*/*/*/*.js', 'node_modules/nodebb-*/*/*/*/*.js', 'node_modules/templates.js/lib/templates.js']
|
||||
files: [
|
||||
'public/src/**/*.js',
|
||||
'node_modules/nodebb-*/*.js', 'node_modules/nodebb-*/**/*.js',
|
||||
'!node_modules/nodebb-*/node_modules/**',
|
||||
'node_modules/templates.js/lib/templates.js',
|
||||
'!node_modules/nodebb-*/.git/**'
|
||||
]
|
||||
},
|
||||
serverUpdated: {
|
||||
files: ['*.js', 'install/*.js', 'src/**/*.js']
|
||||
},
|
||||
templatesUpdated: {
|
||||
files: ['src/views/**/*.tpl', 'node_modules/nodebb-*/*.tpl', 'node_modules/nodebb-*/*/*.tpl', 'node_modules/nodebb-*/*/*/*.tpl', 'node_modules/nodebb-*/*/*/*/*.tpl', 'node_modules/nodebb-*/*/*/*/*/*.tpl']
|
||||
files: [
|
||||
'src/views/**/*.tpl',
|
||||
'node_modules/nodebb-*/*.tpl', 'node_modules/nodebb-*/**/*.tpl',
|
||||
'!node_modules/nodebb-*/node_modules/**',
|
||||
'!node_modules/nodebb-*/.git/**'
|
||||
]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
4
app.js
4
app.js
@@ -149,9 +149,7 @@ function start() {
|
||||
meta.reload();
|
||||
break;
|
||||
case 'js-propagate':
|
||||
meta.js.target[message.target] = meta.js.target[message.target] || {};
|
||||
meta.js.target[message.target].cache = message.cache;
|
||||
meta.js.target[message.target].map = message.map;
|
||||
meta.js.target = message.data;
|
||||
emitter.emit('meta:js.compiled');
|
||||
winston.verbose('[cluster] Client-side javascript and mapping propagated to worker %s', process.pid);
|
||||
break;
|
||||
|
||||
13
loader.js
13
loader.js
@@ -34,8 +34,9 @@ var pidFilePath = __dirname + '/pidfile',
|
||||
|
||||
Loader.init = function(callback) {
|
||||
if (silent) {
|
||||
console.log = function(value) {
|
||||
output.write(value + '\n');
|
||||
console.log = function() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
output.write(args.join(' ') + '\n');
|
||||
};
|
||||
}
|
||||
|
||||
@@ -122,15 +123,11 @@ Loader.addWorkerEvents = function(worker) {
|
||||
Loader.reload();
|
||||
break;
|
||||
case 'js-propagate':
|
||||
Loader.js.target[message.target] = Loader.js.target[message.target] || {};
|
||||
Loader.js.target[message.target].cache = message.cache;
|
||||
Loader.js.target[message.target].map = message.map;
|
||||
Loader.js.target = message.data;
|
||||
|
||||
Loader.notifyWorkers({
|
||||
action: 'js-propagate',
|
||||
cache: message.cache,
|
||||
map: message.map,
|
||||
target: message.target
|
||||
data: message.data
|
||||
}, worker.pid);
|
||||
break;
|
||||
case 'css-propagate':
|
||||
|
||||
@@ -53,9 +53,9 @@
|
||||
"nodebb-plugin-spam-be-gone": "0.4.6",
|
||||
"nodebb-rewards-essentials": "0.0.8",
|
||||
"nodebb-theme-lavender": "3.0.9",
|
||||
"nodebb-theme-persona": "4.0.114",
|
||||
"nodebb-theme-persona": "4.0.115",
|
||||
"nodebb-theme-vanilla": "5.0.61",
|
||||
"nodebb-widget-essentials": "2.0.8",
|
||||
"nodebb-widget-essentials": "2.0.9",
|
||||
"nodemailer": "2.0.0",
|
||||
"nodemailer-sendmail-transport": "1.0.0",
|
||||
"nodemailer-smtp-transport": "^2.4.1",
|
||||
@@ -87,7 +87,7 @@
|
||||
"devDependencies": {
|
||||
"mocha": "~1.13.0",
|
||||
"grunt": "~0.4.5",
|
||||
"grunt-contrib-watch": "^0.6.1"
|
||||
"grunt-contrib-watch": "^1.0.0"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/NodeBB/NodeBB/issues"
|
||||
@@ -112,4 +112,4 @@
|
||||
"url": "https://github.com/barisusakli"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
6
public/language/ar/uploads.json
Normal file
6
public/language/ar/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/bg/uploads.json
Normal file
6
public/language/bg/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Качване на файла…",
|
||||
"select-file-to-upload": "Изберете файл за качване!",
|
||||
"upload-success": "Файлът е качен успешно!",
|
||||
"maximum-file-size": "Най-много %1 КБ"
|
||||
}
|
||||
6
public/language/bn/uploads.json
Normal file
6
public/language/bn/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/cs/uploads.json
Normal file
6
public/language/cs/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/da/uploads.json
Normal file
6
public/language/da/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
"reset.notify.text1": "Wir benachrichtigen dich, dass dein Passwort am %1 erfolgreich geändert wurde.",
|
||||
"reset.notify.text2": "Bitte benachrichtige umgehend einen Administrator, wenn du dies nicht autorisiert hast.",
|
||||
"digest.notifications": "Du hast ungelesene Benachrichtigungen von %1:",
|
||||
"digest.latest_topics": "Neueste Themen vom %1",
|
||||
"digest.latest_topics": "Neueste Themen auf %1",
|
||||
"digest.cta": "Klicke hier, um %1 zu besuchen",
|
||||
"digest.unsub.info": "Diese Zusammenfassung wurde dir aufgrund deiner Abonnement-Einstellungen gesendet.",
|
||||
"digest.no_topics": "Es gab keine aktiven Themen innerhalb %1",
|
||||
|
||||
6
public/language/de/uploads.json
Normal file
6
public/language/de/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Lade Datei hoch...",
|
||||
"select-file-to-upload": "Wähle eine Datei zum Hochladen aus!",
|
||||
"upload-success": "Datei erfolgreich hochgeladen!",
|
||||
"maximum-file-size": "Maximal %1 kb"
|
||||
}
|
||||
@@ -65,7 +65,7 @@
|
||||
"show_email": "Zeige meine E-Mail Adresse an.",
|
||||
"show_fullname": "Zeige meinen kompletten Namen an",
|
||||
"restrict_chats": "Nur Chatnachrichten von Benutzern, denen ich folge, erlauben",
|
||||
"digest_label": "Auszug abonnieren",
|
||||
"digest_label": "Zusammenfassung abonnieren",
|
||||
"digest_description": "Abonniere E-Mail-Benachrichtigungen für dieses Forum (neue Benachrichtigungen und Themen) nach einem festen Zeitplan.",
|
||||
"digest_off": "Aus",
|
||||
"digest_daily": "Täglich",
|
||||
|
||||
6
public/language/el/uploads.json
Normal file
6
public/language/el/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/en@pirate/uploads.json
Normal file
6
public/language/en@pirate/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
"digest.day": "day",
|
||||
"digest.week": "week",
|
||||
"digest.month": "month",
|
||||
"digest.subject": "Digest for %1",
|
||||
|
||||
"notif.chat.subject": "New chat message received from %1",
|
||||
"notif.chat.cta": "Click here to continue the conversation",
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
"cant-remove-last-user": "You can't remove the last user",
|
||||
"cant-delete-chat-message": "You are not allowed to delete this message",
|
||||
|
||||
"already-voting-for-this-post": "You have already voted for this post.",
|
||||
"reputation-system-disabled": "Reputation system is disabled.",
|
||||
"downvoting-disabled": "Downvoting is disabled",
|
||||
"not-enough-reputation-to-downvote": "You do not have enough reputation to downvote this post",
|
||||
|
||||
6
public/language/en_US/uploads.json
Normal file
6
public/language/en_US/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
"invalid-password": "Contraseña no válida",
|
||||
"invalid-username-or-password": "Por favor especifica tanto un usuario como contraseña",
|
||||
"invalid-search-term": "Término de búsqueda inválido",
|
||||
"invalid-pagination-value": "Invalid pagination value, must be at least %1 and at most %2",
|
||||
"invalid-pagination-value": "Número de página inválido, debe estar entre %1 y %2",
|
||||
"username-taken": "Nombre de usuario ocupado",
|
||||
"email-taken": "Correo electrónico ocupado",
|
||||
"email-not-confirmed": "Su cuenta de correo electrónico no ha sido confirmada aún, por favor haga click aquí para confirmarla.",
|
||||
@@ -84,7 +84,7 @@
|
||||
"chat-message-too-long": "Mensaje de Chat es demasiado largo",
|
||||
"cant-edit-chat-message": "No tienes permiso para editar este mensaje",
|
||||
"cant-remove-last-user": "No puedes eliminar el último usuario",
|
||||
"cant-delete-chat-message": "You are not allowed to delete this message",
|
||||
"cant-delete-chat-message": "No tienes permiso para eliminar este mensaje",
|
||||
"reputation-system-disabled": "El sistema de reputación está deshabilitado.",
|
||||
"downvoting-disabled": "La votación negativa está deshabilitada.",
|
||||
"not-enough-reputation-to-downvote": "No tienes suficiente reputación para votar negativo este post",
|
||||
@@ -97,7 +97,7 @@
|
||||
"wrong-login-type-username": "Por favor introduce tu nombre de usuario para acceder",
|
||||
"invite-maximum-met": "Has alcanzado el número máximo de personas invitadas (%1 de %2).",
|
||||
"no-session-found": "¡No se ha encontrado ningún inicio de sesión!",
|
||||
"not-in-room": "User not in room",
|
||||
"no-users-in-room": "No users in this room",
|
||||
"cant-kick-self": "You can't kick yourself from the group"
|
||||
"not-in-room": "El usuario no está en la sala",
|
||||
"no-users-in-room": "No hay usuarios en esta sala",
|
||||
"cant-kick-self": "No te puedes expulsar a ti mismo del grupo"
|
||||
}
|
||||
@@ -65,7 +65,7 @@
|
||||
"posted_in_ago_by": "publicado en %1 %2 por %3",
|
||||
"user_posted_ago": "%1 publicó %2",
|
||||
"guest_posted_ago": "Invitado publicó %1",
|
||||
"last_edited_by": "last edited by %1",
|
||||
"last_edited_by": "Última edición por %1",
|
||||
"norecentposts": "No hay publicaciones recientes",
|
||||
"norecenttopics": "No hay temas recientes",
|
||||
"recentposts": "Publicaciones recientes",
|
||||
@@ -87,8 +87,8 @@
|
||||
"map": "Mapa",
|
||||
"sessions": "Inicios de sesión",
|
||||
"ip_address": "Direcciones IP",
|
||||
"enter_page_number": "Enter page number",
|
||||
"upload_file": "Upload file",
|
||||
"upload": "Upload",
|
||||
"allowed-file-types": "Allowed file types are %1"
|
||||
"enter_page_number": "Escribe el número de página",
|
||||
"upload_file": "Subir archivo",
|
||||
"upload": "Subir",
|
||||
"allowed-file-types": "Los tipos de archivos permitidos son: %1"
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
"details.hidden": "Oculto",
|
||||
"details.hidden_help": "Si está habilitado, este grupo no aparecerá en los listados de grupos, y los usuarios tendrán que ser invitados manualmente",
|
||||
"details.delete_group": "Eliminar grupo",
|
||||
"details.private_system_help": "Private groups is disabled at system level, this option does not do anything",
|
||||
"details.private_system_help": "Los grupos privados están desactivados a nivel de sistema, esta opción no cambiará nada.",
|
||||
"event.updated": "Los detalles del grupo han sido actualizados",
|
||||
"event.deleted": "El grupo \"%1\" ha sido eliminado",
|
||||
"membership.accept-invitation": "Aceptar Invitación",
|
||||
@@ -50,5 +50,5 @@
|
||||
"membership.leave-group": "Dejar el grupo",
|
||||
"membership.reject": "Rechazar",
|
||||
"new-group.group_name": "Nombre de Grupo:",
|
||||
"upload-group-cover": "Upload group cover"
|
||||
"upload-group-cover": "Cargar foto para el grupo"
|
||||
}
|
||||
6
public/language/es/uploads.json
Normal file
6
public/language/es/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/et/uploads.json
Normal file
6
public/language/et/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/fa_IR/uploads.json
Normal file
6
public/language/fa_IR/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/fi/uploads.json
Normal file
6
public/language/fi/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/fr/uploads.json
Normal file
6
public/language/fr/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Envoi du fichier…",
|
||||
"select-file-to-upload": "Sélectionnez un ficher à envoyer",
|
||||
"upload-success": "Fichier envoyé",
|
||||
"maximum-file-size": "%1 Ko maximum"
|
||||
}
|
||||
6
public/language/gl/uploads.json
Normal file
6
public/language/gl/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/he/uploads.json
Normal file
6
public/language/he/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/hu/uploads.json
Normal file
6
public/language/hu/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/id/uploads.json
Normal file
6
public/language/id/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/it/uploads.json
Normal file
6
public/language/it/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/ja/uploads.json
Normal file
6
public/language/ja/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
"password-too-long": "패스워드가 너무 깁니다.",
|
||||
"user-banned": "차단된 사용자입니다.",
|
||||
"user-too-new": "죄송합니다, 첫 번째 게시물은 %1 초 후에 작성할 수 있습니다.",
|
||||
"blacklisted-ip": "Sorry, your IP address has been banned from this community. If you feel this is in error, please contact an administrator.",
|
||||
"blacklisted-ip": "죄송하지만, 당신의 IP는 이 커뮤니티로부터 차단되었습니다. 만약 에러라는 생각이 드신다면 관리자에게 연락해주세요.",
|
||||
"no-category": "존재하지 않는 카테고리입니다.",
|
||||
"no-topic": "존재하지 않는 주제입니다.",
|
||||
"no-post": "존재하지 않는 게시물입니다.",
|
||||
@@ -99,5 +99,5 @@
|
||||
"no-session-found": "로그인 세션을 찾을 수 없습니다.",
|
||||
"not-in-room": "없는 사용자입니다.",
|
||||
"no-users-in-room": "사용자가 없습니다.",
|
||||
"cant-kick-self": "You can't kick yourself from the group"
|
||||
"cant-kick-self": "스스로 이 그룹을 탈퇴할 수 없습니다."
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
"details.hidden": "숨김",
|
||||
"details.hidden_help": "활성 시 그룹 목록에 노출되지 않습니다. 또한 구성원은 초대를 통해서만 가입이 가능합니다.",
|
||||
"details.delete_group": "그룹 삭제",
|
||||
"details.private_system_help": "Private groups is disabled at system level, this option does not do anything",
|
||||
"details.private_system_help": "비공개 그룹은 시스템에 의해 비활성화 되었으며, 이 옵션은 아무 기능도 하지 않습니다",
|
||||
"event.updated": "그룹 정보가 업데이트 되었습니다.",
|
||||
"event.deleted": "%1 그룹이 삭제되었습니다.",
|
||||
"membership.accept-invitation": "초대 수락",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"chat.user_typing": "%1님이 입력 중입니다.",
|
||||
"chat.user_has_messaged_you": "%1님이 메시지를 보냈습니다.",
|
||||
"chat.see_all": "모든 대화 보기",
|
||||
"chat.mark_all_read": "Mark all chats read",
|
||||
"chat.mark_all_read": "읽은 채팅 읽음으로 표시",
|
||||
"chat.no-messages": "대화 기록을 보려면 대화 상대를 선택하세요.",
|
||||
"chat.no-users-in-room": "사용자가 없습니다.",
|
||||
"chat.recent-chats": "최근 대화 내용",
|
||||
|
||||
6
public/language/ko/uploads.json
Normal file
6
public/language/ko/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "파일 업로드 중...",
|
||||
"select-file-to-upload": "업로드할 파일을 선택해 주세요!",
|
||||
"upload-success": "파일이 성공적으로 업로드 되었습니다!",
|
||||
"maximum-file-size": "최대 %1 kb"
|
||||
}
|
||||
@@ -39,7 +39,7 @@
|
||||
"change_username": "사용자명 변경",
|
||||
"change_email": "이메일 변경",
|
||||
"edit": "프로필 수정",
|
||||
"edit-profile": "Edit Profile",
|
||||
"edit-profile": "프로필 수정하기",
|
||||
"default_picture": "기본 아이콘",
|
||||
"uploaded_picture": "사진 업로드",
|
||||
"upload_new_picture": "새 사진 업로드",
|
||||
@@ -92,7 +92,7 @@
|
||||
"open_links_in_new_tab": "외부 링크를 새로운 탭을 사용하여 열람",
|
||||
"enable_topic_searching": "주제 내 검색 허용",
|
||||
"topic_search_help": "활성화 된후 브라우저의 기본 페이지 검색 기능을 연관 주제 검색 기능으로 대신하고 화면에 보여지는 것 뿐만 아니라 주제와 연관된 모든것을 검색합니다.",
|
||||
"scroll_to_my_post": "After posting a reply, show the new post",
|
||||
"scroll_to_my_post": "답글 게시 후 새 포스트 보여주기",
|
||||
"follow_topics_you_reply_to": "답글 단 게시물을 팔로우 합니다.",
|
||||
"follow_topics_you_create": "생성한 주제를 팔로우 합니다.",
|
||||
"grouptitle": "표시할 그룹 이름을 선택하세요.",
|
||||
|
||||
6
public/language/lt/uploads.json
Normal file
6
public/language/lt/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/ms/uploads.json
Normal file
6
public/language/ms/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/nb/uploads.json
Normal file
6
public/language/nb/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
@@ -52,7 +52,7 @@
|
||||
"best": "Beste",
|
||||
"upvoted": "Omhoog gestemd",
|
||||
"downvoted": "Omlaag gestemd",
|
||||
"views": "Gezien",
|
||||
"views": "Weergaven",
|
||||
"reputation": "Reputatie",
|
||||
"read_more": "Lees meer",
|
||||
"more": "Meer",
|
||||
|
||||
@@ -104,9 +104,9 @@
|
||||
"stale.title": "Een nieuw onderwerp maken in de plaats?",
|
||||
"stale.warning": "Het onderwerp waar je op antwoord is vrij oud. Zou je graag een nieuw onderwerp maken met een referentie naar dit onderwerp in je antwoord?",
|
||||
"stale.create": "Maak een nieuw onderwerp",
|
||||
"stale.reply_anyway": "Antwoord toch op dit onderwerp",
|
||||
"stale.reply_anyway": "Reageer toch op dit onderwerp",
|
||||
"link_back": "Re: [%1](%2)",
|
||||
"spam": "Spam",
|
||||
"offensive": "Onbeleefd",
|
||||
"offensive": "Aanstootgevend",
|
||||
"custom-flag-reason": "Geef een reden voor de melding."
|
||||
}
|
||||
6
public/language/nl/uploads.json
Normal file
6
public/language/nl/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/pl/uploads.json
Normal file
6
public/language/pl/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/pt_BR/uploads.json
Normal file
6
public/language/pt_BR/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Fazendo upload do arquivo...",
|
||||
"select-file-to-upload": "Escolha um arquivo para fazer upload!",
|
||||
"upload-success": "Upload realizado com sucesso!",
|
||||
"maximum-file-size": "No máximo %1 kb"
|
||||
}
|
||||
6
public/language/ro/uploads.json
Normal file
6
public/language/ro/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/ru/uploads.json
Normal file
6
public/language/ru/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/rw/uploads.json
Normal file
6
public/language/rw/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/sc/uploads.json
Normal file
6
public/language/sc/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/sk/uploads.json
Normal file
6
public/language/sk/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/sl/uploads.json
Normal file
6
public/language/sl/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/sr/uploads.json
Normal file
6
public/language/sr/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/sv/uploads.json
Normal file
6
public/language/sv/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/th/uploads.json
Normal file
6
public/language/th/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
6
public/language/tr/uploads.json
Normal file
6
public/language/tr/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Dosya yükleniyor...",
|
||||
"select-file-to-upload": "Bir dosya seç!",
|
||||
"upload-success": "Dosya yüklenmesi tamamlandı!",
|
||||
"maximum-file-size": "Maksimum %1 kb"
|
||||
}
|
||||
6
public/language/vi/uploads.json
Normal file
6
public/language/vi/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
@@ -27,7 +27,7 @@
|
||||
"password-too-long": "密码太长",
|
||||
"user-banned": "用户已禁止",
|
||||
"user-too-new": "抱歉,您需要等待 %1 秒后,才可以发帖!",
|
||||
"blacklisted-ip": "Sorry, your IP address has been banned from this community. If you feel this is in error, please contact an administrator.",
|
||||
"blacklisted-ip": "对不起,您的IP地址已被社区禁用。如果您认为这是一个错误,请与管理员联系。",
|
||||
"no-category": "版块不存在",
|
||||
"no-topic": "主题不存在",
|
||||
"no-post": "帖子不存在",
|
||||
@@ -99,5 +99,5 @@
|
||||
"no-session-found": "未登录!",
|
||||
"not-in-room": "用户已不在聊天室中",
|
||||
"no-users-in-room": "这个聊天室中没有用户",
|
||||
"cant-kick-self": "You can't kick yourself from the group"
|
||||
"cant-kick-self": "你不能把自己踢出群组"
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
"details.hidden": "隐藏",
|
||||
"details.hidden_help": "启用此选项后,小组将不在小组列表中展现,成员只能通过邀请加入。",
|
||||
"details.delete_group": "删除小组",
|
||||
"details.private_system_help": "Private groups is disabled at system level, this option does not do anything",
|
||||
"details.private_system_help": "系统禁用了私有群组,这个选项不起任何作用",
|
||||
"event.updated": "小组信息已更新",
|
||||
"event.deleted": "小组 \"%1\" 已被删除",
|
||||
"membership.accept-invitation": "接受邀请",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"chat.user_typing": "%1 正在输入……",
|
||||
"chat.user_has_messaged_you": "%1 向您发送了消息。",
|
||||
"chat.see_all": "查看所有对话",
|
||||
"chat.mark_all_read": "Mark all chats read",
|
||||
"chat.mark_all_read": "将所有聊天标为已读",
|
||||
"chat.no-messages": "请选择接收人,以查看聊天消息历史",
|
||||
"chat.no-users-in-room": "此聊天室中没有用户",
|
||||
"chat.recent-chats": "最近聊天",
|
||||
|
||||
6
public/language/zh_CN/uploads.json
Normal file
6
public/language/zh_CN/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "正在上传文件...",
|
||||
"select-file-to-upload": "请选择需要上传的文件!",
|
||||
"upload-success": "文件上传成功!",
|
||||
"maximum-file-size": "最大 %1 kb"
|
||||
}
|
||||
@@ -39,7 +39,7 @@
|
||||
"change_username": "更改用户名",
|
||||
"change_email": "更改电子邮箱",
|
||||
"edit": "编辑",
|
||||
"edit-profile": "Edit Profile",
|
||||
"edit-profile": "编辑资料",
|
||||
"default_picture": "缺省图标",
|
||||
"uploaded_picture": "已有头像",
|
||||
"upload_new_picture": "上传新头像",
|
||||
@@ -92,7 +92,7 @@
|
||||
"open_links_in_new_tab": "在新标签打开外部链接",
|
||||
"enable_topic_searching": "启用主题内搜索",
|
||||
"topic_search_help": "如果启用此项,主题内搜索会替代浏览器默认的页面搜索,您将可以在整个主题内搜索,而不仅仅只搜索页面上展现的内容。",
|
||||
"scroll_to_my_post": "After posting a reply, show the new post",
|
||||
"scroll_to_my_post": "在提交回复之后显示新帖子",
|
||||
"follow_topics_you_reply_to": "关注您回复的主题",
|
||||
"follow_topics_you_create": "关注您创建的主题",
|
||||
"grouptitle": "选择展示的小组称号",
|
||||
|
||||
6
public/language/zh_TW/uploads.json
Normal file
6
public/language/zh_TW/uploads.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"uploading-file": "Uploading the file...",
|
||||
"select-file-to-upload": "Select a file to upload!",
|
||||
"upload-success": "File uploaded successfully!",
|
||||
"maximum-file-size": "Maximum %1 kb"
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
&[data-state="unloaded"], &[data-state="loading"] {
|
||||
display: inherit;
|
||||
height: 2rem;
|
||||
height: 0;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,21 +16,21 @@
|
||||
});
|
||||
}
|
||||
|
||||
$(window).on('action:ajaxify.contentLoaded', function(ev, data) {
|
||||
var url = data.url;
|
||||
|
||||
selectMenuItem(data.url);
|
||||
setupRestartLinks();
|
||||
|
||||
componentHandler.upgradeDom();
|
||||
});
|
||||
|
||||
$('[component="logout"]').on('click', app.logout);
|
||||
app.alert = launchSnackbar;
|
||||
|
||||
configureSlidemenu();
|
||||
});
|
||||
|
||||
$(window).on('action:ajaxify.contentLoaded', function(ev, data) {
|
||||
var url = data.url;
|
||||
|
||||
selectMenuItem(data.url);
|
||||
setupRestartLinks();
|
||||
|
||||
componentHandler.upgradeDom();
|
||||
});
|
||||
|
||||
function setupKeybindings() {
|
||||
Mousetrap.bind('ctrl+shift+a r', function() {
|
||||
require(['admin/modules/instance'], function(instance) {
|
||||
|
||||
@@ -99,6 +99,48 @@ define('admin/manage/category', [
|
||||
});
|
||||
});
|
||||
|
||||
$('.copy-settings').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
socket.emit('admin.categories.getNames', function(err, categories) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
|
||||
templates.parse('admin/partials/categories/select-category', {
|
||||
categories: categories
|
||||
}, function(html) {
|
||||
function submit() {
|
||||
var formData = modal.find('form').serializeObject();
|
||||
|
||||
socket.emit('admin.categories.copySettingsFrom', {fromCid: formData['select-cid'], toCid: ajaxify.data.category.cid}, function(err) {
|
||||
if (err) {
|
||||
return app.alertError(err.message);
|
||||
}
|
||||
app.alertSuccess('Settings Copied!');
|
||||
ajaxify.refresh();
|
||||
});
|
||||
|
||||
modal.modal('hide');
|
||||
return false;
|
||||
}
|
||||
|
||||
var modal = bootbox.dialog({
|
||||
title: 'Select a Category',
|
||||
message: html,
|
||||
buttons: {
|
||||
save: {
|
||||
label: 'Copy',
|
||||
className: 'btn-primary',
|
||||
callback: submit
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
modal.find('form').on('submit', submit);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
$('.upload-button').on('click', function() {
|
||||
var inputEl = $(this);
|
||||
var cid = inputEl.attr('data-cid');
|
||||
|
||||
@@ -118,25 +118,25 @@ define('forum/search', ['search', 'autocomplete'], function(searchModule, autoco
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var regexStr = searchQuery.replace(/^"/, '').replace(/"$/, '').trim().split(' ').join('|');
|
||||
var regex = new RegExp('(' + regexStr + ')', 'gi');
|
||||
var regexStr = searchQuery.replace(/^"/, '').replace(/"$/, '').trim().split(' ').join('|');
|
||||
var regex = new RegExp('(' + regexStr + ')', 'gi');
|
||||
|
||||
$('.search-result-text').each(function() {
|
||||
var result = $(this);
|
||||
$('.search-result-text p, .search-result-text h4').each(function() {
|
||||
var result = $(this), nested = [];
|
||||
|
||||
var text = result.html().replace(regex, '<strong>$1</strong>');
|
||||
result.html(text).find('img:not(.not-responsive)').addClass('img-responsive').each(function() {
|
||||
$(this).attr('src', $(this).attr('src').replace(/<strong>([\s\S]*?)<\/strong>/gi, '$1'));
|
||||
});
|
||||
|
||||
result.find('a').each(function() {
|
||||
$(this).attr('href', $(this).attr('href').replace(/<strong>([\s\S]*?)<\/strong>/gi, '$1'));
|
||||
});
|
||||
result.find('*').each(function() {
|
||||
$(this).after('<!-- ' + nested.length + ' -->');
|
||||
nested.push($('<div />').append($(this)));
|
||||
});
|
||||
} catch(e) {
|
||||
return;
|
||||
}
|
||||
|
||||
result.html(result.html().replace(regex, '<strong>$1</strong>'));
|
||||
|
||||
for (var i = 0, ii = nested.length; i < ii; i++) {
|
||||
result.html(result.html().replace('<!-- ' + i + ' -->', nested[i].html()));
|
||||
}
|
||||
});
|
||||
|
||||
$('.search-result-text').find('img:not(.not-responsive)').addClass('img-responsive');
|
||||
}
|
||||
|
||||
function handleSavePreferences() {
|
||||
|
||||
@@ -222,10 +222,10 @@ define('forum/topic', [
|
||||
|
||||
function updateTopicTitle() {
|
||||
var span = components.get('navbar/title').find('span');
|
||||
if ($(window).scrollTop() > 50) {
|
||||
span.html(ajaxify.data.title).show();
|
||||
} else {
|
||||
span.html('').hide();
|
||||
if ($(window).scrollTop() > 50 && span.hasClass('hidden')) {
|
||||
span.html(ajaxify.data.title).removeClass('hidden');
|
||||
} else if ($(window).scrollTop() <= 50 && !span.hasClass('hidden')) {
|
||||
span.html('').addClass('hidden');
|
||||
}
|
||||
if ($(window).scrollTop() > 300) {
|
||||
app.removeAlert('bookmark');
|
||||
|
||||
@@ -118,6 +118,8 @@ define('forum/topic/events', [
|
||||
editedPostEl.find('img:not(.not-responsive)').addClass('img-responsive');
|
||||
app.replaceSelfLinks(editedPostEl.find('a'));
|
||||
posts.wrapImagesInLinks(editedPostEl.parent());
|
||||
posts.unloadImages(editedPostEl.parent());
|
||||
posts.loadImages();
|
||||
editedPostEl.fadeIn(250);
|
||||
$(window).trigger('action:posts.edited', data);
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ define('forum/topic/posts', [
|
||||
], function(pagination, infinitescroll, postTools, navigator, components) {
|
||||
|
||||
var Posts = {
|
||||
_threshold: 0
|
||||
_imageLoaderTimeout: undefined
|
||||
};
|
||||
|
||||
Posts.onNewPost = function(data) {
|
||||
@@ -181,10 +181,13 @@ define('forum/topic/posts', [
|
||||
}
|
||||
|
||||
Posts.loadMorePosts = function(direction) {
|
||||
if (!components.get('topic').length || navigator.scrollActive) {
|
||||
if (!components.get('topic').length || navigator.scrollActive || Posts._infiniteScrollTimeout) {
|
||||
return;
|
||||
}
|
||||
|
||||
Posts._infiniteScrollTimeout = setTimeout(function() {
|
||||
delete Posts._infiniteScrollTimeout;
|
||||
}, 1000);
|
||||
var replies = components.get('post').not('[data-index=0]').not('.new');
|
||||
var afterEl = direction > 0 ? replies.last() : replies.first();
|
||||
var after = parseInt(afterEl.attr('data-index'), 10) || 0;
|
||||
@@ -204,7 +207,6 @@ define('forum/topic/posts', [
|
||||
after: after,
|
||||
direction: direction
|
||||
}, function (data, done) {
|
||||
|
||||
indicatorEl.fadeOut();
|
||||
|
||||
if (data && data.posts && data.posts.length) {
|
||||
@@ -235,78 +237,79 @@ define('forum/topic/posts', [
|
||||
};
|
||||
|
||||
Posts.unloadImages = function(posts) {
|
||||
var images = posts.find('[component="post/content"] img:not(.not-responsive)'),
|
||||
scrollTop = $(window).scrollTop(),
|
||||
height = $(document).height();
|
||||
var images = posts.find('[component="post/content"] img:not(.not-responsive)');
|
||||
|
||||
images.each(function() {
|
||||
$(this).attr('data-src', $(this).attr('src'));
|
||||
$(this).attr('data-state', 'unloaded');
|
||||
$(this).attr('src', 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7');
|
||||
$(this).attr('src', 'about:blank');
|
||||
});
|
||||
|
||||
$(window).scrollTop(scrollTop + $(document).height() - height);
|
||||
};
|
||||
|
||||
Posts.loadImages = function(threshold) {
|
||||
/*
|
||||
If threshold is defined, images loaded above this threshold will modify
|
||||
the user's scroll position so they are not scrolled away from content
|
||||
they were reading. Images loaded below this threshold will push down content.
|
||||
if (Posts._imageLoaderTimeout) {
|
||||
clearTimeout(Posts._imageLoaderTimeout);
|
||||
}
|
||||
|
||||
If no threshold is defined, loaded images will push down content, as per
|
||||
default
|
||||
*/
|
||||
Posts._threshold = threshold;
|
||||
Posts._imageLoaderTimeout = setTimeout(function() {
|
||||
/*
|
||||
If threshold is defined, images loaded above this threshold will modify
|
||||
the user's scroll position so they are not scrolled away from content
|
||||
they were reading. Images loaded below this threshold will push down content.
|
||||
|
||||
var images = components.get('post/content').find('img[data-state="unloaded"]'),
|
||||
visible = images.filter(function() {
|
||||
return utils.isElementInViewport(this);
|
||||
}),
|
||||
scrollTop = $(window).scrollTop(),
|
||||
adjusting = false,
|
||||
adjustQueue = [],
|
||||
adjustPosition = function() {
|
||||
adjusting = true;
|
||||
oldHeight = document.body.clientHeight;
|
||||
If no threshold is defined, loaded images will push down content, as per
|
||||
default
|
||||
*/
|
||||
|
||||
// Display the image
|
||||
$(this).attr('data-state', 'loaded');
|
||||
newHeight = document.body.clientHeight;
|
||||
var images = components.get('post/content').find('img[data-state="unloaded"]'),
|
||||
visible = images.filter(function() {
|
||||
return utils.isElementInViewport(this);
|
||||
}),
|
||||
scrollTop = $(window).scrollTop(),
|
||||
adjusting = false,
|
||||
adjustQueue = [],
|
||||
adjustPosition = function() {
|
||||
adjusting = true;
|
||||
oldHeight = document.body.clientHeight;
|
||||
|
||||
var imageRect = this.getBoundingClientRect();
|
||||
if (imageRect.top < Posts._threshold) {
|
||||
scrollTop = scrollTop + (newHeight - oldHeight);
|
||||
$(window).scrollTop(scrollTop);
|
||||
}
|
||||
|
||||
if (adjustQueue.length) {
|
||||
adjustQueue.pop()();
|
||||
} else {
|
||||
adjusting = false;
|
||||
}
|
||||
},
|
||||
oldHeight, newHeight;
|
||||
|
||||
// For each image, reset the source and adjust scrollTop when loaded
|
||||
visible.attr('data-state', 'loading');
|
||||
visible.each(function(index, image) {
|
||||
image = $(image);
|
||||
|
||||
image.on('load', function() {
|
||||
if (!adjusting) {
|
||||
adjustPosition.call(this);
|
||||
} else {
|
||||
adjustQueue.push(adjustPosition.bind(this));
|
||||
// Display the image
|
||||
$(this).attr('data-state', 'loaded');
|
||||
newHeight = document.body.clientHeight;
|
||||
|
||||
var imageRect = this.getBoundingClientRect();
|
||||
if (imageRect.top < threshold) {
|
||||
scrollTop = scrollTop + (newHeight - oldHeight);
|
||||
$(window).scrollTop(scrollTop);
|
||||
}
|
||||
|
||||
if (adjustQueue.length) {
|
||||
adjustQueue.pop()();
|
||||
} else {
|
||||
adjusting = false;
|
||||
}
|
||||
},
|
||||
oldHeight, newHeight;
|
||||
|
||||
// For each image, reset the source and adjust scrollTop when loaded
|
||||
visible.attr('data-state', 'loading');
|
||||
visible.each(function(index, image) {
|
||||
image = $(image);
|
||||
|
||||
image.on('load', function() {
|
||||
if (!adjusting) {
|
||||
adjustPosition.call(this);
|
||||
} else {
|
||||
adjustQueue.push(adjustPosition.bind(this));
|
||||
}
|
||||
});
|
||||
|
||||
image.attr('src', image.attr('data-src'));
|
||||
if (image.parent().attr('href')) {
|
||||
image.parent().attr('href', image.attr('data-src'));
|
||||
}
|
||||
image.removeAttr('data-src');
|
||||
});
|
||||
|
||||
image.attr('src', image.attr('data-src'));
|
||||
if (image.parent().attr('href')) {
|
||||
image.parent().attr('href', image.attr('data-src'));
|
||||
}
|
||||
image.removeAttr('data-src');
|
||||
});
|
||||
}, 250);
|
||||
};
|
||||
|
||||
Posts.wrapImagesInLinks = function(posts) {
|
||||
@@ -321,13 +324,10 @@ define('forum/topic/posts', [
|
||||
Posts.showBottomPostBar = function() {
|
||||
var mainPost = components.get('post', 'index', 0);
|
||||
var posts = $('[component="post"]');
|
||||
var height = $(document).height();
|
||||
if (!!mainPost.length && posts.length > 1 && $('.post-bar').length < 2) {
|
||||
$('.post-bar').clone().appendTo(mainPost);
|
||||
$(window).scrollTop($(window).scrollTop() + $(document).height() - height);
|
||||
} else if (mainPost.length && posts.length < 2) {
|
||||
mainPost.find('.post-bar').remove();
|
||||
$(window).scrollTop($(window).scrollTop() - $(document).height() - height);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;(function(exports) {
|
||||
"use strict";
|
||||
/* globals define, utils */
|
||||
/* globals define, utils, config */
|
||||
|
||||
// export the class if we are in a Node-like system.
|
||||
if (typeof module === 'object' && module.exports === exports) {
|
||||
@@ -100,13 +100,15 @@
|
||||
return style.join('; ') + ';';
|
||||
};
|
||||
|
||||
helpers.generateChildrenCategories = function(category, relative_path) {
|
||||
helpers.generateChildrenCategories = function(category) {
|
||||
var html = '';
|
||||
var relative_path = (typeof config !== 'undefined' ? config.relative_path : require('nconf').get('relative_path'));
|
||||
|
||||
category.children.forEach(function(child) {
|
||||
if (!child) {
|
||||
return;
|
||||
}
|
||||
var link = child.link ? child.link : ('/category/' + child.slug);
|
||||
var link = child.link ? child.link : (relative_path + '/category/' + child.slug);
|
||||
html += '<a href="' + link + '">' +
|
||||
'<span class="fa-stack fa-lg">' +
|
||||
'<i style="color:' + child.bgColor + ';" class="fa fa-circle fa-stack-2x"></i>' +
|
||||
|
||||
@@ -103,7 +103,10 @@ define('navigator', ['forum/pagination', 'components'], function(pagination, com
|
||||
index = parseInt(els.first().attr('data-index'), 10) + 1;
|
||||
}
|
||||
|
||||
var middleOfViewport = $(window).scrollTop() + $(window).height() / 2;
|
||||
var scrollTop = $(window).scrollTop();
|
||||
var windowHeight = $(window).height();
|
||||
var documentHeight = $(document).height();
|
||||
var middleOfViewport = scrollTop + windowHeight / 2;
|
||||
var previousDistance = Number.MAX_VALUE;
|
||||
els.each(function() {
|
||||
var distanceToMiddle = Math.abs(middleOfViewport - $(this).offset().top);
|
||||
@@ -118,12 +121,24 @@ define('navigator', ['forum/pagination', 'components'], function(pagination, com
|
||||
}
|
||||
});
|
||||
|
||||
// If a threshold is undefined, try to determine one based on new index
|
||||
if (threshold === undefined && ajaxify.currentPage.startsWith('topic')) {
|
||||
var anchorEl = components.get('post/anchor', index - 1),
|
||||
anchorRect = anchorEl.get(0).getBoundingClientRect();
|
||||
var atTop = scrollTop === 0 && parseInt(els.first().attr('data-index'), 10) === 0,
|
||||
nearBottom = scrollTop + windowHeight > documentHeight - 100 && parseInt(els.last().attr('data-index'), 10) === count - 1;
|
||||
|
||||
threshold = anchorRect.top;
|
||||
if (atTop) {
|
||||
index = 1;
|
||||
} else if (nearBottom) {
|
||||
index = count;
|
||||
}
|
||||
|
||||
// If a threshold is undefined, try to determine one based on new index
|
||||
if (threshold === undefined) {
|
||||
if (atTop) {
|
||||
threshold = 0;
|
||||
} else {
|
||||
var anchorEl = components.get('post/anchor', index - 1);
|
||||
var anchorRect = anchorEl.get(0).getBoundingClientRect();
|
||||
threshold = anchorRect.top;
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof navigator.callback === 'function') {
|
||||
|
||||
@@ -16,9 +16,10 @@ define('uploader', ['csrf', 'translator'], function(csrf, translator) {
|
||||
};
|
||||
|
||||
module.show = function(data, callback) {
|
||||
var fileSize = data.hasOwnProperty('fileSize') && data.fileSize !== undefined ? parseInt(data.fileSize, 10) : false;
|
||||
parseModal({
|
||||
showHelp: data.hasOwnProperty('showHelp') && data.showHelp !== undefined ? data.showHelp : true,
|
||||
fileSize: data.hasOwnProperty('fileSize') && data.fileSize !== undefined ? parseInt(data.fileSize, 10) : false,
|
||||
fileSize: fileSize,
|
||||
title: data.title || '[[global:upload_file]]',
|
||||
description: data.description || '',
|
||||
button: data.button || '[[global:upload]]',
|
||||
@@ -40,13 +41,17 @@ define('uploader', ['csrf', 'translator'], function(csrf, translator) {
|
||||
});
|
||||
|
||||
uploadForm.submit(function() {
|
||||
onSubmit(uploadModal, callback);
|
||||
onSubmit(uploadModal, fileSize, callback);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
function onSubmit(uploadModal, callback) {
|
||||
module.hideAlerts = function(modal) {
|
||||
$(modal).find('#alert-status, #alert-success, #alert-error, #upload-progress-box').addClass('hide');
|
||||
};
|
||||
|
||||
function onSubmit(uploadModal, fileSize, callback) {
|
||||
function showAlert(type, message) {
|
||||
module.hideAlerts(uploadModal);
|
||||
uploadModal.find('#alert-' + type).translateText(message).removeClass('hide');
|
||||
@@ -57,9 +62,13 @@ define('uploader', ['csrf', 'translator'], function(csrf, translator) {
|
||||
uploadModal.find('#upload-progress-bar').css('width', '0%');
|
||||
uploadModal.find('#upload-progress-box').show().removeClass('hide');
|
||||
|
||||
if (!uploadModal.find('#fileInput').val()) {
|
||||
var fileInput = uploadModal.find('#fileInput');
|
||||
if (!fileInput.val()) {
|
||||
return showAlert('error', '[[uploads:select-file-to-upload]]');
|
||||
}
|
||||
if (!hasValidFileSize(fileInput[0], fileSize)) {
|
||||
return showAlert('error', '[[error:file-too-big, ' + fileSize + ']]');
|
||||
}
|
||||
|
||||
uploadModal.find('#uploadForm').ajaxSubmit({
|
||||
headers: {
|
||||
@@ -107,9 +116,12 @@ define('uploader', ['csrf', 'translator'], function(csrf, translator) {
|
||||
return response;
|
||||
}
|
||||
|
||||
module.hideAlerts = function(modal) {
|
||||
$(modal).find('#alert-status, #alert-success, #alert-error, #upload-progress-box').addClass('hide');
|
||||
};
|
||||
function hasValidFileSize(fileElement, maxSize) {
|
||||
if (window.FileReader && maxSize) {
|
||||
return fileElement.files[0].size <= maxSize * 1000;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return module;
|
||||
});
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
var async = require('async'),
|
||||
db = require('../database'),
|
||||
privileges = require('../privileges'),
|
||||
plugins = require('../plugins'),
|
||||
utils = require('../../public/src/utils');
|
||||
var async = require('async');
|
||||
|
||||
var db = require('../database');
|
||||
var privileges = require('../privileges');
|
||||
var groups = require('../groups');
|
||||
var plugins = require('../plugins');
|
||||
var utils = require('../../public/src/utils');
|
||||
|
||||
module.exports = function(Categories) {
|
||||
|
||||
@@ -17,6 +19,7 @@ module.exports = function(Categories) {
|
||||
db.incrObjectField('global', 'nextCid', next);
|
||||
},
|
||||
function(cid, next) {
|
||||
data.name = data.name || 'Category ' + cid;
|
||||
var slug = cid + '/' + utils.slugify(data.name);
|
||||
var order = data.order || cid; // If no order provided, place it at the end
|
||||
var colours = Categories.assignColours();
|
||||
@@ -58,6 +61,12 @@ module.exports = function(Categories) {
|
||||
], next);
|
||||
},
|
||||
function(results, next) {
|
||||
if (data.cloneFromCid && parseInt(data.cloneFromCid, 10)) {
|
||||
return Categories.copySettingsFrom(data.cloneFromCid, category.cid, next);
|
||||
}
|
||||
next(null, category);
|
||||
},
|
||||
function(category, next) {
|
||||
plugins.fireHook('action:category.create', category);
|
||||
next(null, category);
|
||||
}
|
||||
@@ -65,10 +74,94 @@ module.exports = function(Categories) {
|
||||
};
|
||||
|
||||
Categories.assignColours = function() {
|
||||
var backgrounds = ['#AB4642', '#DC9656', '#F7CA88', '#A1B56C', '#86C1B9', '#7CAFC2', '#BA8BAF', '#A16946'],
|
||||
text = ['#fff', '#fff', '#333', '#fff', '#333', '#fff', '#fff', '#fff'],
|
||||
index = Math.floor(Math.random() * backgrounds.length);
|
||||
var backgrounds = ['#AB4642', '#DC9656', '#F7CA88', '#A1B56C', '#86C1B9', '#7CAFC2', '#BA8BAF', '#A16946'];
|
||||
var text = ['#fff', '#fff', '#333', '#fff', '#333', '#fff', '#fff', '#fff'];
|
||||
var index = Math.floor(Math.random() * backgrounds.length);
|
||||
|
||||
return [backgrounds[index], text[index]];
|
||||
};
|
||||
|
||||
Categories.copySettingsFrom = function(fromCid, toCid, callback) {
|
||||
var destination;
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
async.parallel({
|
||||
source: async.apply(db.getObject, 'category:' + fromCid),
|
||||
destination: async.apply(db.getObject, 'category:' + toCid)
|
||||
}, next);
|
||||
},
|
||||
function (results, next) {
|
||||
if (!results.source) {
|
||||
return next(new Error('[[error:invalid-cid]]'));
|
||||
}
|
||||
destination = results.destination;
|
||||
|
||||
var tasks = [];
|
||||
if (parseInt(results.source.parentCid, 10)) {
|
||||
tasks.push(async.apply(db.sortedSetAdd, 'cid:' + results.source.parentCid + ':children', results.source.order, toCid));
|
||||
}
|
||||
|
||||
if (destination && parseInt(destination.parentCid, 10)) {
|
||||
tasks.push(async.apply(db.sortedSetRemove, 'cid:' + destination.parentCid + ':children', toCid));
|
||||
}
|
||||
|
||||
destination.description = results.source.description;
|
||||
destination.descriptionParsed = results.source.descriptionParsed;
|
||||
destination.icon = results.source.icon;
|
||||
destination.bgColor = results.source.bgColor;
|
||||
destination.color = results.source.color;
|
||||
destination.link = results.source.link;
|
||||
destination.numRecentReplies = results.source.numRecentReplies;
|
||||
destination.class = results.source.class;
|
||||
destination.imageClass = results.source.imageClass;
|
||||
destination.parentCid = results.source.parentCid || 0;
|
||||
|
||||
tasks.push(async.apply(db.setObject, 'category:' + toCid, destination));
|
||||
|
||||
async.series(tasks, next);
|
||||
},
|
||||
function (results, next) {
|
||||
Categories.copyPrivilegesFrom(fromCid, toCid, next);
|
||||
}
|
||||
], function(err) {
|
||||
callback(err, destination);
|
||||
});
|
||||
};
|
||||
|
||||
Categories.copyPrivilegesFrom = function(fromCid, toCid, callback) {
|
||||
var privilegeList = [
|
||||
'find', 'read', 'topics:create', 'topics:reply', 'purge', 'mods',
|
||||
'groups:find', 'groups:read', 'groups:topics:create', 'groups:topics:reply', 'groups:purge', 'groups:moderate'
|
||||
];
|
||||
|
||||
async.each(privilegeList, function(privilege, next) {
|
||||
copyPrivilege(privilege, fromCid, toCid, next);
|
||||
}, callback);
|
||||
};
|
||||
|
||||
function copyPrivilege(privilege, fromCid, toCid, callback) {
|
||||
async.waterfall([
|
||||
function (next) {
|
||||
db.getSortedSetRange('group:cid:' + toCid + ':privileges:' + privilege + ':members', 0, -1, next);
|
||||
},
|
||||
function (currentMembers, next) {
|
||||
async.eachSeries(currentMembers, function(member, next) {
|
||||
groups.leave('cid:' + toCid + ':privileges:' + privilege, member, next);
|
||||
}, next);
|
||||
},
|
||||
function (next) {
|
||||
db.getSortedSetRange('group:cid:' + fromCid + ':privileges:' + privilege + ':members', 0, -1, next);
|
||||
},
|
||||
function (members, next) {
|
||||
if (!members || !members.length) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
async.eachSeries(members, function(member, next) {
|
||||
groups.join('cid:' + toCid + ':privileges:' + privilege, member, next);
|
||||
}, next);
|
||||
}
|
||||
], callback);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ settingsController.get = function(req, res, callback) {
|
||||
user.getSettings(userData.uid, next);
|
||||
},
|
||||
userGroups: function(next) {
|
||||
groups.getUserGroups([userData.uid], next);
|
||||
groups.getUserGroupsFromSet('groups:createtime', [userData.uid], next);
|
||||
},
|
||||
languages: function(next) {
|
||||
languages.list(next);
|
||||
@@ -49,7 +49,9 @@ settingsController.get = function(req, res, callback) {
|
||||
},
|
||||
function(results, next) {
|
||||
userData.settings = results.settings;
|
||||
userData.userGroups = results.userGroups[0];
|
||||
userData.userGroups = results.userGroups[0].filter(function(group) {
|
||||
return group && group.userTitleEnabled && !groups.isPrivilegeGroup(group.name) && group.name !== 'registered-users';
|
||||
});
|
||||
userData.languages = results.languages;
|
||||
userData.homePageRoutes = results.homePageRoutes;
|
||||
userData.ips = results.ips;
|
||||
|
||||
@@ -77,10 +77,17 @@ usersController.banned = function(req, res, next) {
|
||||
};
|
||||
|
||||
usersController.registrationQueue = function(req, res, next) {
|
||||
var page = parseInt(req.query.page, 10) || 1;
|
||||
var itemsPerPage = 20;
|
||||
var start = (page - 1) * 20;
|
||||
var stop = start + itemsPerPage - 1;
|
||||
var invitations;
|
||||
async.parallel({
|
||||
registrationQueueCount: function(next) {
|
||||
db.sortedSetCard('registration:queue', next);
|
||||
},
|
||||
users: function(next) {
|
||||
user.getRegistrationQueue(0, -1, next);
|
||||
user.getRegistrationQueue(start, stop, next);
|
||||
},
|
||||
invites: function(next) {
|
||||
async.waterfall([
|
||||
@@ -118,6 +125,8 @@ usersController.registrationQueue = function(req, res, next) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
var pageCount = Math.max(1, Math.ceil(data.registrationQueueCount / itemsPerPage));
|
||||
data.pagination = pagination.create(page, pageCount);
|
||||
res.render('admin/manage/registration', data);
|
||||
});
|
||||
};
|
||||
@@ -146,7 +155,7 @@ function getUsers(set, section, req, res, next) {
|
||||
var data = {
|
||||
users: results.users,
|
||||
page: page,
|
||||
pageCount: Math.ceil(results.count / resultsPerPage)
|
||||
pageCount: Math.max(1, Math.ceil(results.count / resultsPerPage))
|
||||
};
|
||||
data[section] = true;
|
||||
render(req, res, data);
|
||||
|
||||
@@ -425,9 +425,13 @@ var utils = require('../public/src/utils');
|
||||
};
|
||||
|
||||
Groups.getUserGroups = function(uids, callback) {
|
||||
Groups.getUserGroupsFromSet('groups:visible:createtime', uids, callback);
|
||||
};
|
||||
|
||||
Groups.getUserGroupsFromSet = function (set, uids, callback) {
|
||||
async.waterfall([
|
||||
function(next) {
|
||||
db.getSortedSetRevRange('groups:visible:createtime', 0, -1, next);
|
||||
db.getSortedSetRevRange(set, 0, -1, next);
|
||||
},
|
||||
function(groupNames, next) {
|
||||
var groupSets = groupNames.map(function(name) {
|
||||
|
||||
@@ -93,7 +93,8 @@ module.exports = function(Groups) {
|
||||
bodyShort: '[[groups:request.notification_title, ' + username + ']]',
|
||||
bodyLong: '[[groups:request.notification_text, ' + username + ', ' + groupName + ']]',
|
||||
nid: 'group:' + groupName + ':uid:' + uid + ':request',
|
||||
path: '/groups/' + utils.slugify(groupName)
|
||||
path: '/groups/' + utils.slugify(groupName),
|
||||
from: uid
|
||||
}, next);
|
||||
},
|
||||
owners: function(next) {
|
||||
|
||||
22
src/meta.js
22
src/meta.js
@@ -61,20 +61,16 @@ var async = require('async'),
|
||||
async.apply(plugins.clearRequireCache),
|
||||
async.apply(plugins.reload),
|
||||
async.apply(plugins.reloadRoutes),
|
||||
async.apply(Meta.css.minify),
|
||||
async.apply(Meta.js.minify, 'nodebb.min.js'),
|
||||
async.apply(Meta.js.minify, 'acp.min.js'),
|
||||
async.apply(Meta.sounds.init),
|
||||
async.apply(Meta.templates.compile),
|
||||
async.apply(auth.reloadRoutes),
|
||||
function(next) {
|
||||
async.parallel([
|
||||
async.apply(Meta.js.minify, 'nodebb.min.js'),
|
||||
async.apply(Meta.js.minify, 'acp.min.js'),
|
||||
async.apply(Meta.css.minify),
|
||||
async.apply(Meta.sounds.init),
|
||||
async.apply(Meta.templates.compile),
|
||||
async.apply(auth.reloadRoutes),
|
||||
function(next) {
|
||||
Meta.config['cache-buster'] = utils.generateUUID();
|
||||
templates.flush();
|
||||
next();
|
||||
}
|
||||
], next);
|
||||
Meta.config['cache-buster'] = utils.generateUUID();
|
||||
templates.flush();
|
||||
next();
|
||||
}
|
||||
], function(err) {
|
||||
if (!err) {
|
||||
|
||||
@@ -43,7 +43,8 @@ module.exports = function(Meta) {
|
||||
path.join(__dirname, '../../public/vendor/fontawesome/less'),
|
||||
path.join(__dirname, '../../public/vendor/bootstrap/less')
|
||||
],
|
||||
source = '@import "font-awesome";';
|
||||
source = '@import "font-awesome";',
|
||||
acpSource = '@import "font-awesome";';
|
||||
|
||||
plugins.lessFiles = filterMissingFiles(plugins.lessFiles);
|
||||
plugins.cssFiles = filterMissingFiles(plugins.cssFiles);
|
||||
@@ -67,21 +68,21 @@ module.exports = function(Meta) {
|
||||
|
||||
source += '\n@import (inline) "..' + path.sep + '..' + path.sep + 'public/vendor/jquery/css/smoothness/jquery-ui-1.10.4.custom.min.css";';
|
||||
source += '\n@import (inline) "..' + path.sep + '..' + path.sep + 'public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css";';
|
||||
source += '\n@import (inline) "..' + path.sep + '..' + path.sep + 'public/vendor/colorpicker/colorpicker.css";';
|
||||
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/flags.less";';
|
||||
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/blacklist.less";';
|
||||
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/generics.less";';
|
||||
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/mixins.less";';
|
||||
source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/global.less";';
|
||||
source = '@import "./theme";\n' + source;
|
||||
|
||||
var acpSource = '\n@import "..' + path.sep + 'public/less/admin/admin";\n' + source;
|
||||
acpSource += '\n@import "..' + path.sep + 'public/less/admin/admin";\n';
|
||||
acpSource += '\n@import "..' + path.sep + 'public/less/generics.less";';
|
||||
acpSource += '\n@import (inline) "..' + path.sep + 'public/vendor/colorpicker/colorpicker.css";';
|
||||
|
||||
source = '@import "./theme";\n' + source;
|
||||
|
||||
var fromFile = nconf.get('from-file') || '';
|
||||
async.parallel([
|
||||
|
||||
async.series([
|
||||
function(next) {
|
||||
if (fromFile.match('clientLess')) {
|
||||
winston.info('[minifier] Compiling front-end LESS files skipped');
|
||||
@@ -149,7 +150,7 @@ module.exports = function(Meta) {
|
||||
});
|
||||
}
|
||||
|
||||
Meta.css.commitToFile = function(filename) {
|
||||
Meta.css.commitToFile = function(filename, callback) {
|
||||
var file = (filename === 'acpCache' ? 'admin' : 'stylesheet') + '.css';
|
||||
|
||||
fs.writeFile(path.join(__dirname, '../../public/' + file), Meta.css[filename], function(err) {
|
||||
@@ -159,6 +160,8 @@ module.exports = function(Meta) {
|
||||
winston.error('[meta/css] ' + err.message);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
@@ -184,7 +187,6 @@ module.exports = function(Meta) {
|
||||
return;
|
||||
}
|
||||
|
||||
winston.verbose('[meta/css] Running PostCSS Plugins');
|
||||
postcss([ autoprefixer ]).process(lessOutput.css).then(function (result) {
|
||||
result.warnings().forEach(function (warn) {
|
||||
winston.verbose(warn.toString());
|
||||
@@ -194,7 +196,11 @@ module.exports = function(Meta) {
|
||||
|
||||
// Save the compiled CSS in public/ so things like nginx can serve it
|
||||
if (nconf.get('isPrimary') === 'true') {
|
||||
Meta.css.commitToFile(destination);
|
||||
return Meta.css.commitToFile(destination, function() {
|
||||
if (typeof callback === 'function') {
|
||||
callback(null, result.css);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
|
||||
@@ -89,6 +89,8 @@ module.exports = function(Meta) {
|
||||
return;
|
||||
}
|
||||
|
||||
winston.verbose('[meta/js] Minifying ' + target);
|
||||
|
||||
var forkProcessParams = setupDebugging();
|
||||
var minifier = Meta.js.minifierProc = fork('minifier.js', [], forkProcessParams);
|
||||
|
||||
@@ -110,20 +112,19 @@ module.exports = function(Meta) {
|
||||
winston.verbose('[meta/js] ' + target + ' minification complete');
|
||||
minifier.kill();
|
||||
|
||||
if (process.send) {
|
||||
if (process.send && Meta.js.target['nodebb.min.js'] && Meta.js.target['acp.min.js']) {
|
||||
process.send({
|
||||
action: 'js-propagate',
|
||||
cache: Meta.js.target[target].cache,
|
||||
map: Meta.js.target[target].map,
|
||||
target: target
|
||||
data: Meta.js.target
|
||||
});
|
||||
}
|
||||
|
||||
Meta.js.commitToFile(target);
|
||||
Meta.js.commitToFile(target, function() {
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
callback();
|
||||
}
|
||||
break;
|
||||
case 'error':
|
||||
winston.error('[meta/js] Could not compile ' + target + ': ' + message.message);
|
||||
@@ -185,15 +186,15 @@ module.exports = function(Meta) {
|
||||
}
|
||||
};
|
||||
|
||||
Meta.js.commitToFile = function(target) {
|
||||
Meta.js.commitToFile = function(target, callback) {
|
||||
fs.writeFile(path.join(__dirname, '../../public/' + target), Meta.js.target[target].cache, function (err) {
|
||||
if (err) {
|
||||
winston.error('[meta/js] ' + err.message);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
winston.verbose('[meta/js] ' + target + ' committed to disk.');
|
||||
emitter.emit('meta:js.compiled');
|
||||
callback();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -472,7 +472,7 @@ var async = require('async'),
|
||||
return true;
|
||||
}
|
||||
|
||||
return !(notifObj.mergeId === (mergeId + '|' + differentiator) && idx !== modifyIndex);
|
||||
return !(notifObj.mergeId === (mergeId + (differentiator ? '|' + differentiator : '')) && idx !== modifyIndex);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
var async = require('async'),
|
||||
var async = require('async');
|
||||
|
||||
db = require('../../database'),
|
||||
groups = require('../../groups'),
|
||||
categories = require('../../categories'),
|
||||
privileges = require('../../privileges'),
|
||||
plugins = require('../../plugins'),
|
||||
Categories = {};
|
||||
var db = require('../../database');
|
||||
var groups = require('../../groups');
|
||||
var categories = require('../../categories');
|
||||
var privileges = require('../../privileges');
|
||||
var plugins = require('../../plugins');
|
||||
var Categories = {};
|
||||
|
||||
Categories.create = function(socket, data, callback) {
|
||||
if(!data) {
|
||||
if (!data) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ Categories.purge = function(socket, cid, callback) {
|
||||
};
|
||||
|
||||
Categories.update = function(socket, data, callback) {
|
||||
if(!data) {
|
||||
if (!data) {
|
||||
return callback(new Error('[[error:invalid-data]]'));
|
||||
}
|
||||
|
||||
@@ -108,4 +108,8 @@ function copyPrivilegesToChildrenRecursive(category, privilegeGroups, callback)
|
||||
});
|
||||
}
|
||||
|
||||
Categories.copySettingsFrom = function(socket, data, callback) {
|
||||
categories.copySettingsFrom(data.fromCid, data.toCid, callback);
|
||||
};
|
||||
|
||||
module.exports = Categories;
|
||||
@@ -158,7 +158,7 @@ module.exports = function(User) {
|
||||
return user;
|
||||
}).filter(Boolean);
|
||||
|
||||
async.mapLimit(users, 20, function(user, next) {
|
||||
async.map(users, function(user, next) {
|
||||
if (!user) {
|
||||
return next(null, user);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
"use strict";
|
||||
|
||||
var async = require('async'),
|
||||
winston = require('winston'),
|
||||
nconf = require('nconf'),
|
||||
var async = require('async');
|
||||
var winston = require('winston');
|
||||
var nconf = require('nconf');
|
||||
|
||||
db = require('../database'),
|
||||
meta = require('../meta'),
|
||||
user = require('../user'),
|
||||
topics = require('../topics'),
|
||||
batch = require('../batch'),
|
||||
plugins = require('../plugins'),
|
||||
emailer = require('../emailer'),
|
||||
utils = require('../../public/src/utils');
|
||||
var db = require('../database');
|
||||
var meta = require('../meta');
|
||||
var user = require('../user');
|
||||
var topics = require('../topics');
|
||||
var plugins = require('../plugins');
|
||||
var emailer = require('../emailer');
|
||||
var utils = require('../../public/src/utils');
|
||||
|
||||
(function(Digest) {
|
||||
Digest.execute = function(interval) {
|
||||
@@ -100,7 +99,7 @@ var async = require('async'),
|
||||
}
|
||||
|
||||
emailer.send('digest', userObj.uid, {
|
||||
subject: '[' + meta.config.title + '] Digest for ' + now.getFullYear()+ '/' + (now.getMonth()+1) + '/' + now.getDate(),
|
||||
subject: '[' + meta.config.title + '] [[email:digest.subject, ' + (now.getFullYear()+ '/' + (now.getMonth()+1) + '/' + now.getDate()) + ']]',
|
||||
username: userObj.username,
|
||||
userslug: userObj.userslug,
|
||||
url: nconf.get('url'),
|
||||
|
||||
@@ -105,7 +105,8 @@
|
||||
<button type="button" class="btn btn-default btn-block <!-- IF category.parent.name -->hide<!-- ENDIF category.parent.name -->" data-action="setParent"><i class="fa fa-sitemap"></i> (None)</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<hr/>
|
||||
<button class="btn btn-info btn-block copy-settings"><i class="fa fa-files-o"></i> Copy Settings From</button>
|
||||
<hr />
|
||||
<button class="btn btn-danger btn-block purge"><i class="fa fa-eraser"></i> Purge Category</button>
|
||||
</div>
|
||||
|
||||
@@ -55,6 +55,8 @@
|
||||
</tr>
|
||||
<!-- END users -->
|
||||
</table>
|
||||
|
||||
<!-- IMPORT partials/paginator.tpl -->
|
||||
</div>
|
||||
|
||||
<div class="invitations panel panel-success">
|
||||
|
||||
@@ -12,4 +12,14 @@
|
||||
<!-- END categories -->
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="cloneFromCid">(Optional) Clone Settings From Category</label>
|
||||
<select class="form-control" name="cloneFromCid" id="cloneFromCid">
|
||||
<option value=""></option>
|
||||
<!-- BEGIN categories -->
|
||||
<option value="{categories.cid}">{categories.name}</option>
|
||||
<!-- END categories -->
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
10
src/views/admin/partials/categories/select-category.tpl
Normal file
10
src/views/admin/partials/categories/select-category.tpl
Normal file
@@ -0,0 +1,10 @@
|
||||
<form type="form">
|
||||
<div class="form-group">
|
||||
<label for="select-cid">Select Category</label>
|
||||
<select class="form-control" name="select-cid" id="select-cid">
|
||||
<!-- BEGIN categories -->
|
||||
<option value="{categories.cid}">{categories.name}</option>
|
||||
<!-- END categories -->
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
@@ -85,7 +85,7 @@ function initializeNodeBB(callback) {
|
||||
plugins.init(app, middleware, next);
|
||||
},
|
||||
function(next) {
|
||||
async.parallel([
|
||||
async.series([
|
||||
async.apply(meta.templates.compile),
|
||||
async.apply(!skipJS ? meta.js.minify : meta.js.getFromFile, 'nodebb.min.js'),
|
||||
async.apply(!skipJS ? meta.js.minify : meta.js.getFromFile, 'acp.min.js'),
|
||||
|
||||
Reference in New Issue
Block a user