Merge branch 'master' into v0.4.x

This commit is contained in:
Julian Lam
2014-05-02 23:54:25 -04:00
111 changed files with 1633 additions and 326 deletions

View File

@@ -31,7 +31,9 @@ Each plugin package contains a configuration file called ``plugin.json``. Here i
"description": "Your plugin's description",
"url": "Absolute URL to your plugin or a Github repository",
"library": "./my-plugin.js",
"staticDir": "/assets",
"staticDirs": {
"images": "public/images"
},
"less": [
"assets/style.less"
],
@@ -45,7 +47,9 @@ The ``id`` property is a unique name that identifies the plugin.
The ``library`` property is a relative path to the library in your package. It is automatically loaded by NodeBB (if the plugin is activated).
The ``staticDir`` property is a path (relative to your plugin's root) to a directory that NodeBB will expose to the public at the route ``/plugins/{YOUR-PLUGIN-ID}``.
The ``staticDirs`` property is an object hash that maps out paths (relative to your plugin's root) to a directory that NodeBB will expose to the public at the route ``/plugins/{YOUR-PLUGIN-ID}``.
* e.g. The ``staticDirs`` hash in the sample configuration maps ``/path/to/your/plugin/public/images`` to ``/plugins/my-plugin/images``
The ``less`` property contains an array of paths (relative to your plugin's directory), that will be precompiled into the CSS served by NodeBB.

View File

@@ -182,4 +182,12 @@ Executed whenever a post is created or edited, after it is saved into the databa
``action:user.set``
^^^^^^^^^^^^^^^^^^^^^
Useful for things like awarding badges or achievements after a user has reached some value (ex. 100 posts)
Parameters: field (str), value, type ('set', 'increment', or 'decrement')
Useful for things like awarding badges or achievements after a user has reached some value (ex. 100 posts)
``action:settings.set``
^^^^^^^^^^^^^^^^^^^^^
Parameters: hash (str), object (obj)
Useful if your plugins want to cache settings instead of pulling from DB everytime a method is called. Listen to this and refresh accordingly.

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "ملف",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "دردشة",
"notify_me": "تنبه من ردود جديدة في هذا الموضوع",
"quote": "اقتبس",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Sledovat toto téma",
"quote": "Citovat",

View File

@@ -45,16 +45,16 @@
"views": "Aufrufe",
"reputation": "Reputation",
"read_more": "weiterlesen",
"posted_ago_by_guest": "Gespostet %1 von Gast",
"posted_ago_by_guest": "%1 verfasst von einem Gast",
"posted_ago_by": "Geposted %1 von %2",
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "Geposted in %1 %2 von %3",
"posted_in_ago": "Geposted in %1",
"posted_ago": "schrieb %1",
"posted_in_ago_by_guest": "verfasst in %1 %2 von einem Gast",
"posted_in_ago_by": "Verfasst in %1 %2 von %3",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "antwortete %1",
"user_posted_ago": "1% schrieb %2",
"guest_posted_ago": "Guest posted %1",
"last_edited_by_ago": "zuletzt editirt von %1 %2",
"guest_posted_ago": "Gast schrieb %1",
"last_edited_by_ago": "zuletzt editiert von %1 %2",
"norecentposts": "Keine aktuellen Beiträge",
"norecenttopics": "Keine aktuellen Themen",
"recentposts": "Aktuelle Beiträge",

View File

@@ -4,9 +4,10 @@
"topic_id_placeholder": "Topic ID eingeben",
"no_topics_found": "Keine passende Themen gefunden.",
"no_posts_found": "Keine Beiträge gefunden!",
"post_is_deleted": "This post is deleted!",
"post_is_deleted": "Dieser Beitrag wurde gelöscht!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by": "Geschrieben von %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Werde bei neues Antworten auf dieses Thema benachrichtigt.",
"quote": "zitieren",
@@ -40,7 +41,7 @@
"thread_tools.lock": "Thema schließen",
"thread_tools.unlock": "Thema öffnen",
"thread_tools.move": "Thema verschieben",
"thread_tools.move_all": "Move All",
"thread_tools.move_all": "Alle verschieben",
"thread_tools.fork": "Thema aufspalten",
"thread_tools.delete": "Thema löschen",
"thread_tools.delete_confirm": "Sind Sie sicher, dass Sie dieses Thema löschen möchten?",
@@ -87,7 +88,7 @@
"composer.thumb_remove": "Felder leeren",
"composer.drag_and_drop_images": "Bilder hier reinziehen",
"composer.upload_instructions": "Zum Hochladen Bilder hier reinziehen.",
"more_users_and_guests": "%1 more user(s) and %2 guest(s)",
"more_users": "%1 more user(s)",
"more_guests": "%1 more guest(s)"
"more_users_and_guests": "%1 weitere(r) Nutzer und %2 Gäste",
"more_users": "%1 weitere(r) Nutzer",
"more_guests": "%1 weitere Gäste"
}

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profile",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Be notified of new replies in this topic",
"quote": "Quote",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -12,7 +12,7 @@
"user_made_post": "<strong>%1</strong> made a new post",
"new_message_from": "New message from <strong>%1</strong>",
"upvoted_your_post": "<strong>%1</strong> has upvoted your post.",
"favourited_your_post": "<strong>%1</strong> has favourited your post.",
"favourited_your_post": "<strong>%1</strong> has favorited your post.",
"user_flagged_post": "<strong>%1</strong> flagged a post.",
"user_posted_to": "<strong>%1</strong> has posted a reply to: <strong>%2</strong>"
}

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profile",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Be notified of new replies in this topic",
"quote": "Quote",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -9,7 +9,7 @@
"user.following": "Gente que sigue %1 ",
"user.followers": "Seguidores de %1",
"user.posts": "Posteos de %1",
"user.topics": "Topics created by %1",
"user.topics": "Temas creados por %1",
"user.favourites": "Publicaciones favoritas de %1 ",
"user.settings": "Preferencias del Usuario"
}

View File

@@ -3,12 +3,12 @@
"update_password": "Actualizar contraseña",
"password_changed.title": "Contraseña editada",
"password_changed.message": "<p>La contraseña fue modificada con éxito, por favor <a href=\"/login\">inicia sesión de nuevo</a>.",
"wrong_reset_code.title": "Código de reinicio Incorrecto",
"wrong_reset_code.title": "Código de reinicio incorrecto",
"wrong_reset_code.message": "El código de reinicio ingresado no es correcto. Por favor inténtalo de nuevo o <a href=\"/reset\">pide un nuevo código</a>.",
"new_password": "Nueva Contraseña",
"repeat_password": "Confirmar Contraseña",
"enter_email": "Por favor ingresa tu <strong>correo electrónico</strong> y te enviaremos un correo con indicaciones para inicializar tu cuenta.",
"enter_email_address": "Enter Email Address",
"enter_email_address": "Introduce tu correo electrónico",
"password_reset_sent": "Reinicio de contraseña enviado",
"invalid_email": "Correo Electrónico no válido o inexistente!"
}

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Perfil",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Serás notificado cuando haya nuevas respuestas en este tema",
"quote": "Citar",

View File

@@ -45,16 +45,16 @@
"views": "Vaatamised",
"reputation": "Reputatsioon",
"read_more": "loe veel",
"posted_ago_by_guest": "posted %1 by Guest",
"posted_ago_by": "posted %1 by %2",
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",
"last_edited_by_ago": "last edited by %1 %2",
"posted_ago_by_guest": "postitatud %1 tagasi külalise poolt",
"posted_ago_by": "postitatud %1 tagasi kasutaja %2 poolt",
"posted_ago": "postitatud %1 tagasi",
"posted_in_ago_by_guest": "postitatud kategooriasse %1 %2 tagasi külalise poolt",
"posted_in_ago_by": "postitatud kategooriasse %1 %2 aega tagasi kasutaja %3 poolt",
"posted_in_ago": "postitatud kategooriasse %1 %2 tagasi",
"replied_ago": "vastas %1 tagasi",
"user_posted_ago": "kasutaja %1 postitas %2 tagasi",
"guest_posted_ago": "Külaline postitas %1",
"last_edited_by_ago": "viimati muudetud kasutaja %1 poolt %2 tagasi",
"norecentposts": "Hiljutisi postitusi ei ole",
"norecenttopics": "Hiljutisi teemasid ei ole",
"recentposts": "Hiljutised postitused",
@@ -65,6 +65,6 @@
"offline": "Väljas",
"email": "Emaili aadress",
"language": "Keel",
"guest": "Guest",
"guests": "Guests"
"guest": "Külaline",
"guests": "Külalised"
}

View File

@@ -4,9 +4,10 @@
"topic_id_placeholder": "Sisesta teema ID",
"no_topics_found": "Teemasid ei leitud!",
"no_posts_found": "Postitusi ei leitud!",
"post_is_deleted": "This post is deleted!",
"post_is_deleted": "See postitus on kustutatud!",
"profile": "Profiil",
"posted_by": "Posted by %1",
"posted_by": "Postitatud %1 poolt",
"posted_by_guest": "Posted by Guest",
"chat": "Vestlus",
"notify_me": "Saa teateid uutest postitustest selles teemas",
"quote": "Tsiteeri",
@@ -40,7 +41,7 @@
"thread_tools.lock": "Lukusta teema",
"thread_tools.unlock": "Eemalda märgistatud teema",
"thread_tools.move": "Liiguta teema",
"thread_tools.move_all": "Move All",
"thread_tools.move_all": "Liiguta kõik",
"thread_tools.fork": "Fork Topic",
"thread_tools.delete": "Kustuta teema",
"thread_tools.delete_confirm": "Oled kindel, et soovid kustutada antud teema?",
@@ -87,7 +88,7 @@
"composer.thumb_remove": "Puhasta väljad",
"composer.drag_and_drop_images": "Lohista pildid siia",
"composer.upload_instructions": "Lae üles pilte lohistades need siia.",
"more_users_and_guests": "%1 more user(s) and %2 guest(s)",
"more_users": "%1 more user(s)",
"more_guests": "%1 more guest(s)"
"more_users_and_guests": "%1 kasutaja(t) ja %2 külalist",
"more_users": "veel %1 kasutaja(t)",
"more_guests": "veel %1 külalist"
}

View File

@@ -19,7 +19,7 @@
"no-post": "چنین دیدگاهی نداریم",
"no-group": "چنین گروهی نداریم",
"no-user": "چنین کاربری نداریم",
"no-teaser": "Teaser doesn't exist",
"no-teaser": "چکیدهٔ دیدگاه نیست",
"no-privileges": "شما پروانه‌های کافی برای این کار را ندارید.",
"category-disabled": "دسته از کار افتاد.",
"topic-locked": "جستار بسته شده",

View File

@@ -39,18 +39,18 @@
"alert.unfollow": "شما دیگر %1 را دنبال نمی‌کنید!",
"alert.follow": "اکنون %1 را دنبال می‌کنید.",
"online": "حاضر",
"users": "Users",
"topics": "Topics",
"users": "کاربران",
"topics": "جُستارها",
"posts": "دیدگاه‌ها",
"views": "بازدیدها",
"reputation": "Reputation",
"reputation": "اعتبار",
"read_more": "read more",
"posted_ago_by_guest": "posted %1 by Guest",
"posted_ago_by": "posted %1 by %2",
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",
@@ -65,6 +65,6 @@
"offline": "غایب",
"email": "رایانامه",
"language": "زبان",
"guest": "Guest",
"guests": "Guests"
"guest": "مهمان",
"guests": "مهمان‌ها"
}

View File

@@ -1,5 +1,5 @@
{
"success": "Success",
"success": "موفقیت",
"topic-post": "دیدگاه شما باموفقیت فرستاده شد.",
"authentication-successful": "اعتبارسنجی موفق",
"settings-saved": "تنظیمات اندوخته شد."

View File

@@ -4,9 +4,10 @@
"topic_id_placeholder": "ID جستار را بنویسید",
"no_topics_found": "هیچ جستاری یافت نشد!",
"no_posts_found": "دیدگاهی یافت نشد!",
"post_is_deleted": "This post is deleted!",
"post_is_deleted": "این دیدگاه پاک شده!",
"profile": "نمایه",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "گفتگو",
"notify_me": "از پاسخ‌های تازه در جستار آگاه شوید",
"quote": "نقل قول",
@@ -40,7 +41,7 @@
"thread_tools.lock": "قفل کردن جستار",
"thread_tools.unlock": "باز کردن جستار",
"thread_tools.move": "جابجا کردن جستار",
"thread_tools.move_all": "Move All",
"thread_tools.move_all": "جابجایی همه",
"thread_tools.fork": "شاخه ساختن از جستار",
"thread_tools.delete": "پاک کردن جستار",
"thread_tools.delete_confirm": "آیا از پاک کردن این جستار اطمینان دارید؟",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profiili",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Keskustele",
"notify_me": "Ilmoita, kun tähän keskusteluun tulee uusia viestejä",
"quote": "Lainaa",

View File

@@ -1,49 +1,49 @@
{
"invalid-data": "Invalid Data",
"not-logged-in": "You don't seem to be logged in.",
"invalid-cid": "Invalid Category ID",
"invalid-tid": "Invalid Topic ID",
"invalid-pid": "Invalid Post ID",
"invalid-uid": "Invalid User ID",
"invalid-username": "Invalid Username",
"invalid-email": "Invalid Email",
"invalid-title": "Invalid title",
"invalid-user-data": "Invalid User Data",
"invalid-password": "Invalid Password",
"invalid-pagination-value": "Invalid pagination value",
"username-taken": "Username taken",
"email-taken": "Email taken",
"user-banned": "User banned",
"no-category": "Category doesn't exist",
"no-topic": "Topic doesn't exist",
"no-post": "Post doesn't exist",
"no-group": "Group doesn't exist",
"no-user": "User doesn't exist",
"no-teaser": "Teaser doesn't exist",
"no-privileges": "You don't have enough privileges for this action.",
"category-disabled": "Category disabled",
"topic-locked": "Topic Locked",
"still-uploading": "Please wait for uploads to complete.",
"content-too-short": "Please enter a longer post. At least %1 characters.",
"title-too-short": "Please enter a longer title. At least %1 characters.",
"title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.",
"too-many-posts": "You can only post every %1 seconds.",
"file-too-big": "Maximum allowed file size is %1 kbs",
"cant-vote-self-post": "You cannot vote for your own post",
"already-favourited": "You already favourited this post",
"already-unfavourited": "You alread unfavourited this post",
"cant-ban-other-admins": "You can't ban other admins!",
"invalid-image-type": "Invalid image type",
"group-name-too-short": "Group name too short",
"group-already-exists": "Group already exists",
"group-name-change-not-allowed": "Group name change not allowed",
"post-already-deleted": "Post already deleted",
"post-already-restored": "Post already restored",
"topic-already-deleted": "Topic already deleted",
"topic-already-restored": "Topic already restored",
"topic-thumbnails-are-disabled": "Topic thumbnails are disabled.",
"invalid-file": "Invalid File",
"uploads-are-disabled": "Uploads are disabled",
"signature-too-long": "Signature can't be longer than %1 characters!",
"cant-chat-with-yourself": "You can't chat with yourself!"
"invalid-data": "Données Invalides",
"not-logged-in": "Vous ne semblez pas être connecté.",
"invalid-cid": "ID de Catégorie Invalide",
"invalid-tid": "ID de Sujet Invalide",
"invalid-pid": "ID de Message Invalide",
"invalid-uid": "ID Utilisateur Invalide",
"invalid-username": "Nom d'utilisateur Invalide",
"invalid-email": "Email Invalide",
"invalid-title": "Titre Invalide",
"invalid-user-data": "Données Utilisateur Invalides",
"invalid-password": "Mot de passe Invalide",
"invalid-pagination-value": "Valeur de pagination invalide",
"username-taken": "Nom dutilisateur déjà utilisé",
"email-taken": "Email déjà utilisé",
"user-banned": "Utilisateur banni",
"no-category": "Cette catégorie n'existe pas",
"no-topic": "Ce sujet n'existe pas",
"no-post": "Ce message n'existe pas",
"no-group": "Ce groupe n'existe pas",
"no-user": "Cet utilisateur n'existe pas",
"no-teaser": "Laperçu n'existe pas",
"no-privileges": "Vous n'avez pas les privilèges nécessaires pour effectuer cette action.",
"category-disabled": "Catégorie désactivée",
"topic-locked": "Sujet Verrouillé",
"still-uploading": "Veuillez patienter pendant le téléchargement.",
"content-too-short": "Veuillez entrer un message plus long. %1 caractères minimum.",
"title-too-short": "Veuillez entrer un titre plus long. %1 caractères minimum.",
"title-too-long": "Veuillez entrer un titre plus court. Les titres ne peuvent excéder %1 caractères.",
"too-many-posts": "Vous ne pouvez poster que toutes les %1 secondes.",
"file-too-big": "La taille maximum des fichiers est de %1 kbs.",
"cant-vote-self-post": "Vous ne pouvez pas voter pour vos propres messages",
"already-favourited": "Vous avez déjà mis ce message en favoris",
"already-unfavourited": "Vous avez déjà enlevé ce message des favoris",
"cant-ban-other-admins": "Vous ne pouvez pas bannir les autres administrateurs!",
"invalid-image-type": "Type dimage invalide",
"group-name-too-short": "Nom de groupe trop court",
"group-already-exists": "Ce groupe existe déjà",
"group-name-change-not-allowed": "Modification du nom de groupe non permise",
"post-already-deleted": "Message déjà supprimé",
"post-already-restored": "Message déjà restauré",
"topic-already-deleted": "Sujet déjà supprimé",
"topic-already-restored": "Sujet déjà restauré",
"topic-thumbnails-are-disabled": "Miniatures de sujet désactivés",
"invalid-file": "Fichier Invalide",
"uploads-are-disabled": "Téléchargements désactivés",
"signature-too-long": "La signature ne peut dépasser %1 caractères!",
"cant-chat-with-yourself": "Vous ne pouvez chatter avec vous même!"
}

View File

@@ -45,16 +45,16 @@
"views": "Vues",
"reputation": "Réputation",
"read_more": "En lire plus",
"posted_ago_by_guest": "posted %1 by Guest",
"posted_ago_by": "posted %1 by %2",
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",
"last_edited_by_ago": "last edited by %1 %2",
"posted_ago_by_guest": "posté %1 par un Invité",
"posted_ago_by": "posté %1 par %2",
"posted_ago": "posté %1",
"posted_in_ago_by_guest": "posté dans %1 %2 par un Invité",
"posted_in_ago_by": "posté dans %1 %2 par %3",
"posted_in_ago": "posté dans %1 %2",
"replied_ago": "répondu %1",
"user_posted_ago": "%1 a posté %2",
"guest_posted_ago": "Un Invité a posté %1",
"last_edited_by_ago": "dernière édition par %1 %2",
"norecentposts": "Aucun Message Récent",
"norecenttopics": "Aucun Sujet Récent",
"recentposts": "Messages Récents",
@@ -65,6 +65,6 @@
"offline": "Hors ligne",
"email": "Email",
"language": "Langue",
"guest": "Guest",
"guests": "Guests"
"guest": "Invité",
"guests": "Invités"
}

View File

@@ -9,7 +9,7 @@
"user.following": "Personnes que %1 suit",
"user.followers": "Personnes qui suivent %1",
"user.posts": "Message écrit par %1",
"user.topics": "Topics created by %1",
"user.topics": "Sujets créés par %1",
"user.favourites": "Messages favoris de %1",
"user.settings": "Préférences Utilisateur"
}

View File

@@ -4,9 +4,10 @@
"topic_id_placeholder": "Entrer l'ID du Sujet",
"no_topics_found": "Aucun sujet trouvé !",
"no_posts_found": "Aucun message trouvé!",
"post_is_deleted": "This post is deleted!",
"post_is_deleted": "Ce message a été supprimé!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by": "Posté par %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Être notifié des réponses dans ce sujet",
"quote": "Citer",
@@ -40,7 +41,7 @@
"thread_tools.lock": "Verrouiller le sujet",
"thread_tools.unlock": "Déverouiller le sujet",
"thread_tools.move": "Déplacer le sujet",
"thread_tools.move_all": "Move All",
"thread_tools.move_all": "Déplacer tout",
"thread_tools.fork": "Scinder le sujet",
"thread_tools.delete": "Supprimer le sujet",
"thread_tools.delete_confirm": "Êtes vous sûr de vouloir supprimer ce sujet?",
@@ -87,7 +88,7 @@
"composer.thumb_remove": "Effacer les champs",
"composer.drag_and_drop_images": "Glisser-déposer ici les images",
"composer.upload_instructions": "Uploader des images par glisser-déposer.",
"more_users_and_guests": "%1 more user(s) and %2 guest(s)",
"more_users": "%1 more user(s)",
"more_guests": "%1 more guest(s)"
"more_users_and_guests": "%1 autre(s) utilisateur(s) et %2 invité(s)",
"more_users": "%1 autre(s) utilisateur(s)",
"more_guests": "%1 autre(s) invité(s)"
}

View File

@@ -49,7 +49,7 @@
"digest_daily": "Quotidien",
"digest_weekly": "Hebdomadaire",
"digest_monthly": "Mensuel",
"has_no_follower": "Cet utilisateur n'a aucun suiveur :(",
"has_no_follower": "Cet utilisateur n'est suivi par personnne :(",
"follows_no_one": "Cet utilisateur ne suit personne :(",
"has_no_posts": "Ce membre n'a rien posté pour le moment",
"has_no_topics": "L'utilsateur n'a encore créé aucun sujet.",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "פרופיל",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "צ'אט",
"notify_me": "קבל התראה כאשר יש תגובות חדשות בנושא זה",
"quote": "ציטוט",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -11,4 +11,4 @@
"enter_email_address": "Email cím megadása",
"password_reset_sent": "Jelszó-visszaállítás elküldve",
"invalid_email": "Helytelen E-mail cím / Nem létező E-mail cím!"
}
}

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Értesítést kérek az új hozzászólásokról ebben a topikban",
"quote": "Idéz",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profilo",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Ricevi notifiche di nuove risposte in questa discussione",
"quote": "Citazione",

View File

@@ -4,4 +4,4 @@
"browsing": "閲覧中",
"no_replies": "返事はまだありません",
"share_this_category": "この板を共有"
}
}

View File

@@ -46,4 +46,4 @@
"uploads-are-disabled": "アップロードが無効された",
"signature-too-long": "署名は最大%1文字までです",
"cant-chat-with-yourself": "自分にチャットすることはできません!"
}
}

View File

@@ -50,7 +50,7 @@
"posted_ago": "%1に投稿された",
"posted_in_ago_by_guest": "%1に %2 ゲストが投稿",
"posted_in_ago_by": "%1 %2に %3 が投稿",
"posted_in_ago": "%1 に投稿",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "%1 に返答",
"user_posted_ago": "%1 が%2に投稿",
"guest_posted_ago": "ゲストが%1に投稿",
@@ -67,4 +67,4 @@
"language": "言語",
"guest": "ゲスト",
"guests": "ゲスト"
}
}

View File

@@ -2,4 +2,4 @@
"name": "日本語",
"code": "ja",
"dir": "ltr"
}
}

View File

@@ -5,4 +5,4 @@
"alternative_logins": "ほかのログイン方法",
"failed_login_attempt": "ログインに失敗しました.ユーザー名やパスワードをご確認ください。",
"login_successful": "ログインしました!"
}
}

View File

@@ -4,4 +4,4 @@
"chat.send": "送信",
"chat.no_active": "チャットはありません。",
"chat.user_typing": "%1 は入力中 ..."
}
}

View File

@@ -15,4 +15,4 @@
"favourited_your_post": "<strong>%1</strong>はあなたのポストをお気に入りにしました。",
"user_flagged_post": "<strong>%1</strong> ポストを報告しました。",
"user_posted_to": "<strong>%1</strong> は <strong>%2</strong> への返事を作成しました。"
}
}

View File

@@ -12,4 +12,4 @@
"user.topics": "%1が作成したスレッド",
"user.favourites": "%1のお気に入りポスト",
"user.settings": "ユーザー設定"
}
}

View File

@@ -4,4 +4,4 @@
"week": "最近 1 週",
"month": "最近 1 ヶ月",
"no_recent_topics": "最近のスレッドはありません。"
}
}

View File

@@ -15,4 +15,4 @@
"alternative_registration": "ほかの登録方法",
"terms_of_use": "利用規約",
"agree_to_terms_of_use": "利用規約に同意する"
}
}

View File

@@ -11,4 +11,4 @@
"enter_email_address": "メールアドレスを入力してください",
"password_reset_sent": "パスワードリセットのメールを送信しました",
"invalid_email": "このメールアドレスは存在しません"
}
}

View File

@@ -3,4 +3,4 @@
"topic-post": "成功に投稿しました。",
"authentication-successful": "認証が成功しました",
"settings-saved": "設定を保存しました。"
}
}

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "このポストが削除されます!",
"profile": "プロフィール",
"posted_by": "%1 のポスト",
"posted_by_guest": "Posted by Guest",
"chat": "チャット",
"notify_me": "このスレッドに新しいポストが投稿された際に通知する",
"quote": "引用",
@@ -90,4 +91,4 @@
"more_users_and_guests": "%1 more user(s) and %2 guest(s)",
"more_users": "%1 more user(s)",
"more_guests": "%1 more guest(s)"
}
}

View File

@@ -6,4 +6,4 @@
"selected": "選択済み",
"all": "すべて",
"topics_marked_as_read.success": "すべてのスレッドを既読にしました。"
}
}

View File

@@ -59,4 +59,4 @@
"topics_per_page": "ページ毎のスレッド数",
"posts_per_page": "ページ毎のポスト数",
"notification_sounds": "通知が来たとき音を流す"
}
}

View File

@@ -5,4 +5,4 @@
"search": "検索",
"enter_username": "検索するユーザー名を入力してください",
"load_more": "もっと表示"
}
}

View File

@@ -1,49 +1,49 @@
{
"invalid-data": "Invalid Data",
"not-logged-in": "You don't seem to be logged in.",
"invalid-cid": "Invalid Category ID",
"invalid-tid": "Invalid Topic ID",
"invalid-pid": "Invalid Post ID",
"invalid-uid": "Invalid User ID",
"invalid-username": "Invalid Username",
"invalid-email": "Invalid Email",
"invalid-title": "Invalid title",
"invalid-user-data": "Invalid User Data",
"invalid-password": "Invalid Password",
"invalid-pagination-value": "Invalid pagination value",
"username-taken": "Username taken",
"email-taken": "Email taken",
"user-banned": "User banned",
"no-category": "Category doesn't exist",
"no-topic": "Topic doesn't exist",
"no-post": "Post doesn't exist",
"no-group": "Group doesn't exist",
"no-user": "User doesn't exist",
"no-teaser": "Teaser doesn't exist",
"no-privileges": "You don't have enough privileges for this action.",
"category-disabled": "Category disabled",
"topic-locked": "Topic Locked",
"still-uploading": "Please wait for uploads to complete.",
"content-too-short": "Please enter a longer post. At least %1 characters.",
"title-too-short": "Please enter a longer title. At least %1 characters.",
"title-too-long": "Please enter a shorter title. Titles can't be longer than %1 characters.",
"too-many-posts": "You can only post every %1 seconds.",
"file-too-big": "Maximum allowed file size is %1 kbs",
"cant-vote-self-post": "You cannot vote for your own post",
"already-favourited": "You already favourited this post",
"already-unfavourited": "You alread unfavourited this post",
"cant-ban-other-admins": "You can't ban other admins!",
"invalid-image-type": "Invalid image type",
"group-name-too-short": "Group name too short",
"group-already-exists": "Group already exists",
"group-name-change-not-allowed": "Group name change not allowed",
"post-already-deleted": "Post already deleted",
"post-already-restored": "Post already restored",
"topic-already-deleted": "Topic already deleted",
"topic-already-restored": "Topic already restored",
"topic-thumbnails-are-disabled": "Topic thumbnails are disabled.",
"invalid-file": "Invalid File",
"uploads-are-disabled": "Uploads are disabled",
"signature-too-long": "Signature can't be longer than %1 characters!",
"cant-chat-with-yourself": "You can't chat with yourself!"
"invalid-data": "Klaidingi duomenys",
"not-logged-in": "Atrodo, kad jūs neesate prisijungęs.",
"invalid-cid": "Klaidingas kategorijos ID",
"invalid-tid": "Klaidingas temos ID",
"invalid-pid": "Klaidingas pranešimo ID",
"invalid-uid": "Klaidingas vartotojo ID",
"invalid-username": "Klaidingas vartotojo vardas",
"invalid-email": "Klaidingas el. pašto adresas",
"invalid-title": "Klaidingas pavadinimas",
"invalid-user-data": "Klaidingi vartotojo duomenys",
"invalid-password": "Klaidingas slaptažodis",
"invalid-pagination-value": "Klaidinga puslapiavimo reikšmė",
"username-taken": "Vartotojo vardas jau užimtas",
"email-taken": "El. pašto adresas jau užimtas",
"user-banned": "Vartotojas užblokuotas",
"no-category": "Kategorija neegzistuoja",
"no-topic": "Tema neegzistuoja",
"no-post": "Pranešimas neegzistuoja",
"no-group": "Grupė neegzistuoja",
"no-user": "Vartotojas neegzistuoja",
"no-teaser": "Trumpas skelbimas neegzistuoja!",
"no-privileges": "Jūs neturite teisės atlikti šį veiksmą.",
"category-disabled": "Kategorija išjungta",
"topic-locked": "Tema užrakinta",
"still-uploading": "Prašome palaukti kol bus baigti visi kėlimai į serverį",
"content-too-short": "Jūsų pranešimas turėtų būti ilgesnis, mažiausiai %1 simbolių.",
"title-too-short": "Pavadinimas turėtų būtų ilgesnis, mažiausiai %1 simbolių.",
"title-too-long": "Pavadinimas turėtų būti trumpesnis. Maksimalus leistinas ilgis- %1 simbolių.",
"too-many-posts": "Rašyti pranešimus galite kas %1 sekundžių.",
"file-too-big": "Maksimalus leistinas failo dydis %1 kb",
"cant-vote-self-post": "Jūs negalite balsuoti už savo pranešimą",
"already-favourited": "Jūs jau esate pamėgę šį pranešimą",
"already-unfavourited": "Jūs jau esate pašalinę šį pranešimą iš mėgiamų sąrašo",
"cant-ban-other-admins": "Jūs negalite užblokuoti kitų administratorių!",
"invalid-image-type": "Klaidingas paveikslėlio tipas",
"group-name-too-short": "Grupės pavadinimas per trumpas",
"group-already-exists": "Tokia grupė jau egzistuoja",
"group-name-change-not-allowed": "Grupės pavadinimas keitimas neleidžiamas",
"post-already-deleted": "Pranešimas jau yra anksčiau ištrintas",
"post-already-restored": "Pranešimas jau anksčiau atkurtas",
"topic-already-deleted": "Tema jau anksčiau buvo ištrinta",
"topic-already-restored": "Tema jau anksčiau buvo atkurta",
"topic-thumbnails-are-disabled": "Temos paveikslėliai neleidžiami.",
"invalid-file": "Klaidingas failas",
"uploads-are-disabled": "Įkėlimai neleidžiami",
"signature-too-long": "Parašas negali būti ilgesnis negu %1 simboliai!",
"cant-chat-with-yourself": "Jūs negalite susirašinėti su savimi!"
}

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profilis",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Susirašinėti",
"notify_me": "Gauti pranešimus apie naujus atsakymus šioje temoje",
"quote": "Cituoti",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Sembang",
"notify_me": "Kekal dimaklumkan berkenaan respon dalam topik ini",
"quote": "Petikan",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Bli varslet om nye svar i dette emnet",
"quote": "Siter",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profiel",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Krijg notificaties van nieuwe reacties op dit onderwerp",
"quote": "Citeren",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",
@@ -63,8 +63,8 @@
"dnd": "Nie przeszkadzać",
"invisible": "Niewidoczny",
"offline": "Niedostępny",
"email": "Email",
"language": "Language",
"email": "Adres e-mail",
"language": "Język",
"guest": "Guest",
"guests": "Guests"
}

View File

@@ -3,5 +3,5 @@
"chat.placeholder": "napisz wiadomość tutaj i naciśnij enter",
"chat.send": "Wyślij",
"chat.no_active": "Nie prowadzisz obecnie żadnych rozmów.",
"chat.user_typing": "%1 is typing ..."
"chat.user_typing": "%1 pisze..."
}

View File

@@ -7,12 +7,12 @@
"outgoing_link_message": "Opuszczasz",
"continue_to": "Kontynuuj do",
"return_to": "Wróć do",
"new_notification": "New Notification",
"you_have_unread_notifications": "You have unread notifications.",
"user_made_post": "<strong>%1</strong> made a new post",
"new_message_from": "New message from <strong>%1</strong>",
"new_notification": "Nowe powiadomienie",
"you_have_unread_notifications": "Masz nieprzeczytane powiadomienia.",
"user_made_post": "<strong>%1</strong> napisał nowy post",
"new_message_from": "Nowa wiadomość od <strong>%1</strong>",
"upvoted_your_post": "<strong>%1</strong> has upvoted your post.",
"favourited_your_post": "<strong>%1</strong> has favourited your post.",
"user_flagged_post": "<strong>%1</strong> flagged a post.",
"user_posted_to": "<strong>%1</strong> has posted a reply to: <strong>%2</strong>"
"user_posted_to": "<strong>%1</strong> dodał odpowiedź do <strong>%2</strong>"
}

View File

@@ -9,7 +9,7 @@
"user.following": "Obserwowani przez %1",
"user.followers": "Obserwujący %1",
"user.posts": "Posty napisane przez %1",
"user.topics": "Topics created by %1",
"user.topics": "Wątki stworzone przez %1",
"user.favourites": "Ulubione posty %1",
"user.settings": "Ustawienia użytkownika"
}

View File

@@ -8,7 +8,7 @@
"new_password": "Nowe hasło",
"repeat_password": "Powtórz hasło",
"enter_email": "Podaj swój <strong>adres e-mail</strong> i wyślemy ci wiadomość z instrukcjami jak zresetować hasło.",
"enter_email_address": "Enter Email Address",
"enter_email_address": "Wpisz swój adres e-mail",
"password_reset_sent": "Instrukcje zostały wysłane",
"invalid_email": "Niepoprawny adres e-mail."
}

View File

@@ -6,7 +6,8 @@
"no_posts_found": "Nie znaleziono żadnych postów.",
"post_is_deleted": "This post is deleted!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by": "Napisane przez %1",
"posted_by_guest": "Posted by Guest",
"chat": "Czat",
"notify_me": "Powiadamiaj mnie o nowych odpowiedziach w tym wątku",
"quote": "Cytuj",
@@ -77,7 +78,7 @@
"composer.help": "Pomoc",
"composer.discard": "Odrzuć",
"composer.submit": "Wyślij",
"composer.replying_to": "Replying to %1",
"composer.replying_to": "Odpowiadanie na %1",
"composer.new_topic": "Nowy wątek",
"composer.uploading": "wysyłanie...",
"composer.thumb_url_label": "Wklej adres miniaturki wątku",

View File

@@ -21,7 +21,7 @@
"chat": "Rozmawiaj",
"follow": "Śledź",
"unfollow": "Przestań śledzić",
"profile_update_success": "Profile has been updated successfully!",
"profile_update_success": "Profil został zaktualizowany pomyślnie!",
"change_picture": "Zmień zdjęcie",
"edit": "Edytuj",
"uploaded_picture": "Przesłane zdjęcie",
@@ -32,7 +32,7 @@
"change_password_error_wrong_current": "Twoje aktualne hasło nie jest poprawne!",
"change_password_error_length": "Hasło jest za krótkie!",
"change_password_error_match": "Hasła muszą pasować!",
"change_password_error_privileges": "You do not have the rights to change this password.",
"change_password_error_privileges": "Nie masz uprawnień do zmiany tego hasła.",
"change_password_success": "Twoje hasło jest zaktualizowane!",
"confirm_password": "Potwierdź hasło",
"password": "Hasło",
@@ -45,10 +45,10 @@
"show_email": "Wyświetlaj mój adres e-mail",
"digest_label": "Subscribe to Digest",
"digest_description": "Subscribe to email updates for this forum (new notifications and topics) according to a set schedule",
"digest_off": "Off",
"digest_daily": "Daily",
"digest_weekly": "Weekly",
"digest_monthly": "Monthly",
"digest_off": "Wyłączone",
"digest_daily": "Codziennie",
"digest_weekly": "Co tydzień",
"digest_monthly": "Co miesiąc",
"has_no_follower": "Ten użytkownik nie ma jeszcze żadnych obserwujących",
"follows_no_one": "Użytkownik jeszcze nikogo nie obsweruje.",
"has_no_posts": "Użytkownik nie napisał jeszcze żadnych postów.",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Perfil",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Bate Papo",
"notify_me": "Ser notificado a cada nova resposta",
"quote": "Citar",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Профиль",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Чат",
"notify_me": "Сообщать мне об ответах в этой теме",
"quote": "Цитировать",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Perfilu",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Tzarra",
"notify_me": "Imbia·mi notìficas pro is rispostas noas a custa arresonada",
"quote": "Mèntova",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -8,7 +8,7 @@
"new_password": "Nové heslo",
"repeat_password": "Potvrdenie hesla",
"enter_email": "Zadajte svoju <strong>emailovú adresu</strong> a my Vám pošleme informácie, ako môžete obnoviť svoje heslo.",
"enter_email_address": "Enter Email Address",
"enter_email_address": "Zadajte e-mail",
"password_reset_sent": "Obnova hesla odoslaná",
"invalid_email": "Zlý email / Email neexistuje!"
}

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Sledovať túto tému",
"quote": "Citovať",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chatt",
"notify_me": "Få notiser om nya svar i detta ämne",
"quote": "Citera",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -1,5 +1,5 @@
{
"name": "ภาษาอังกฤษ (สหราชอาณาจักร / แคนาดา)",
"code": "th",
"code": "en_GB",
"dir": "ltr"
}

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "รายละเอียด",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "แชท",
"notify_me": "แจ้งเตือนเมื่อการตอบใหม่ในกระทู้นี้",
"quote": "คำอ้างอิง",

View File

@@ -45,16 +45,16 @@
"views": "Görüntülemeler",
"reputation": "Saygınlık",
"read_more": "daha fazla oku",
"posted_ago_by_guest": "posted %1 by Guest",
"posted_ago_by": "posted %1 by %2",
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",
"last_edited_by_ago": "last edited by %1 %2",
"posted_ago_by_guest": "Ziyaretçi tarafından %1 yayımlandı",
"posted_ago_by": "%2 tarafından %1 yayımlandı",
"posted_ago": "%1 yayımlandı",
"posted_in_ago_by_guest": "%1 içinde Ziyaretçi tarafından %2 yayımlandı",
"posted_in_ago_by": "%1 içinde %3 tarafından %2 yayımlandı",
"posted_in_ago": "%1 içinde %2 yayımlandı",
"replied_ago": "%1 yanıtlandı",
"user_posted_ago": "%1 %2 yayımladı",
"guest_posted_ago": "Ziyaretçi %1 yayımladı",
"last_edited_by_ago": "en son %1 tarafından %2 düzenlendi",
"norecentposts": "Güncel İletiler Yok",
"norecenttopics": "Güncel Başlıklar Yok",
"recentposts": "Güncel İletiler",
@@ -65,6 +65,6 @@
"offline": "Çevrimdışı",
"email": "E-posta",
"language": "Dil",
"guest": "Guest",
"guests": "Guests"
"guest": "Ziyaretçi",
"guests": "Ziyaretçiler"
}

View File

@@ -4,9 +4,10 @@
"topic_id_placeholder": "Başlık ID gir",
"no_topics_found": "Hiç konu bulunamadı!",
"no_posts_found": "Hiç bir ileti bulunamadı!",
"post_is_deleted": "This post is deleted!",
"post_is_deleted": "Bu ileti silinmiş!",
"profile": "Profil",
"posted_by": "Posted by %1",
"posted_by": "%1 tarafından gönderildi",
"posted_by_guest": "Posted by Guest",
"chat": "Sohbet",
"notify_me": "Bu konudaki cevaplardan haberdar ol",
"quote": "Alıntı",
@@ -40,7 +41,7 @@
"thread_tools.lock": "Başlığı Kitle",
"thread_tools.unlock": "Başlığı Aç",
"thread_tools.move": "Başlığı Taşı",
"thread_tools.move_all": "Move All",
"thread_tools.move_all": "Hepsini Taşı",
"thread_tools.fork": "Başlığı Ayır",
"thread_tools.delete": "Başlığı Sil",
"thread_tools.delete_confirm": "Bu başlığı gerçekten silmek istiyor musun?",
@@ -87,7 +88,7 @@
"composer.thumb_remove": "Alanları temizle",
"composer.drag_and_drop_images": "Resimleri buraya taşıyıp bırakabilirsiniz",
"composer.upload_instructions": "Resimleri taşıyıp bırakarak yükleyebilirsiniz.",
"more_users_and_guests": "%1 more user(s) and %2 guest(s)",
"more_users": "%1 more user(s)",
"more_guests": "%1 more guest(s)"
"more_users_and_guests": "%1 tane daha kullanıcı ve %2 ziyaretçi",
"more_users": "%1 tane daha kullanıcı",
"more_guests": "%1 tane daha ziyaretçi"
}

View File

@@ -50,7 +50,7 @@
"posted_ago": "Đã viết %1",
"posted_in_ago_by_guest": "Đã viết trong %1 %2 bởi Khách",
"posted_in_ago_by": "Đã viết trong %1 %2 bởi %3",
"posted_in_ago": "Đã viết trong %1",
"posted_in_ago": "được đăng trong %1 %2",
"replied_ago": "Đã trả lời %1",
"user_posted_ago": "%1 đã viết %2",
"guest_posted_ago": "Khách đã viết %1",

View File

@@ -1,5 +1,5 @@
{
"name": "Tiếng Việt",
"code": "vi",
"name": "Tiếng Anh (Vương Quốc Anh/Canada)",
"code": "en_GB",
"dir": "ltr"
}

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "Bài gửi này đã bị xóa!",
"profile": "Hồ sơ",
"posted_by": "Được viết bởi %1",
"posted_by_guest": "Posted by Guest",
"chat": "Chat",
"notify_me": "Được thông báo khi có trả lời mới trong chủ đề này",
"quote": "Trích dẫn",

View File

@@ -1,14 +1,14 @@
{
"invalid-data": "Invalid Data",
"not-logged-in": "You don't seem to be logged in.",
"invalid-cid": "Invalid Category ID",
"invalid-tid": "Invalid Topic ID",
"invalid-pid": "Invalid Post ID",
"invalid-uid": "Invalid User ID",
"invalid-username": "Invalid Username",
"invalid-email": "Invalid Email",
"invalid-title": "Invalid title",
"invalid-user-data": "Invalid User Data",
"invalid-data": "无效数据",
"not-logged-in": "你看起来还没有登陆",
"invalid-cid": "无效的板块ID",
"invalid-tid": "无效的话题ID",
"invalid-pid": "无效的帖子ID",
"invalid-uid": "无效的用户ID",
"invalid-username": "无效用户名",
"invalid-email": "无效电邮",
"invalid-title": "无效标题",
"invalid-user-data": "无效用户数据",
"invalid-password": "Invalid Password",
"invalid-pagination-value": "Invalid pagination value",
"username-taken": "Username taken",

View File

@@ -50,7 +50,7 @@
"posted_ago": "发布于 %1",
"posted_in_ago_by_guest": "游客发布于 %1 %2",
"posted_in_ago_by": "%3 在 %1 发布于 %2",
"posted_in_ago": "发布在 %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "%1 回复",
"user_posted_ago": "%1 于 %2 发布",
"guest_posted_ago": "游客发布于 %1",

View File

@@ -8,7 +8,7 @@
"new_password": "新的密码",
"repeat_password": "确认密码",
"enter_email": "请输入您的<strong>Email地址</strong>,我们会发送邮件告诉您如何重置密码。",
"enter_email_address": "Enter Email Address",
"enter_email_address": "输入邮箱地址",
"password_reset_sent": "密码重置邮件已发送。",
"invalid_email": "非法的邮箱地址/邮箱不存在!"
}

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "This post is deleted!",
"profile": "资料",
"posted_by": "Posted by %1",
"posted_by_guest": "Posted by Guest",
"chat": "聊天",
"notify_me": "该主题有新回复时通知我",
"quote": "引用",

View File

@@ -43,8 +43,8 @@
"max": "最大.",
"settings": "设置",
"show_email": "显示我的邮箱",
"digest_label": "Subscribe to Digest",
"digest_description": "Subscribe to email updates for this forum (new notifications and topics) according to a set schedule",
"digest_label": "订阅摘要",
"digest_description": "按照计划订阅邮件提醒( 新通知和话题 )",
"digest_off": "关闭",
"digest_daily": "今天",
"digest_weekly": "本周",

View File

@@ -50,7 +50,7 @@
"posted_ago": "posted %1",
"posted_in_ago_by_guest": "posted in %1 %2 by Guest",
"posted_in_ago_by": "posted in %1 %2 by %3",
"posted_in_ago": "posted in %1",
"posted_in_ago": "posted in %1 %2",
"replied_ago": "replied %1",
"user_posted_ago": "%1 posted %2",
"guest_posted_ago": "Guest posted %1",

View File

@@ -7,6 +7,7 @@
"post_is_deleted": "帖子已被刪除!",
"profile": "資料",
"posted_by": "由 %1 發布",
"posted_by_guest": "Posted by Guest",
"chat": "聊天",
"notify_me": "該主題有新回覆時通知我",
"quote": "引用",

View File

@@ -83,13 +83,13 @@ var ajaxify = ajaxify || {};
app.processPage();
ajaxify.widgets.render(tpl_url, url, function(err) {
$('#content, #footer').stop(true, true).removeClass('ajaxifying');
ajaxify.initialLoad = false;
ajaxify.widgets.render(tpl_url, url);
app.refreshTitle(url);
$(window).trigger('action:ajaxify.end', {url: url});
});
$('#content, #footer').stop(true, true).removeClass('ajaxifying');
ajaxify.initialLoad = false;
app.refreshTitle(url);
$(window).trigger('action:ajaxify.end', {url: url});
}, url);
return true;

View File

@@ -117,7 +117,7 @@ var socket,
});
socket.on('reconnecting', function (data, attempt) {
if(attempt === config.maxReconnectionAttempts) {
if(attempt === parseInt(config.maxReconnectionAttempts, 10)) {
socket.socket.reconnectionAttempts = 0;
socket.socket.reconnectionDelay = config.reconnectionDelay;
return;

View File

@@ -255,6 +255,9 @@ define(['forum/pagination', 'forum/topic/threadTools', 'forum/topic/postTools',
} else if(!user.length && data.online) {
user = createUserIcon(data.uid, data.picture, data.userslug, data.username);
activeEl.append(user);
activeEl.find('a[data-uid] img').tooltip({
placement: 'top'
});
}
}

View File

@@ -88,10 +88,12 @@ define(['taskbar', 'string', 'sounds'], function(taskbar, S, sounds) {
socket.on('event:chats.userStartTyping', function(withUid) {
var modal = module.getModal(withUid);
var chatContent = modal.find('#chat-content');
modal.find('.user-typing')
.removeClass('hide')
.appendTo(chatContent);
scrollToBottom(chatContent);
var atBottom = chatContent[0].scrollHeight - chatContent.scrollTop() === chatContent.innerHeight();
modal.find('.user-typing').removeClass('hide').appendTo(chatContent);
if (atBottom) {
scrollToBottom(chatContent);
}
});
socket.on('event:chats.userStopTyping', function(withUid) {
@@ -164,6 +166,20 @@ define(['taskbar', 'string', 'sounds'], function(taskbar, S, sounds) {
handle: '.modal-header'
});
chatModal.find('.modal-content').resizable({
minHeight: 250,
minWidth: 400
});
chatModal.find('.modal-content').on('resize', function(event, ui) {
var totalHeight = chatModal.find('.modal-content').outerHeight() - chatModal.find('.modal-header').outerHeight();
var padding = parseInt(chatModal.find('.modal-body').css('padding-top'), 10) + parseInt(chatModal.find('.modal-body').css('padding-bottom'), 10);
var contentMargin = parseInt(chatModal.find('#chat-content').css('margin-top'), 10) + parseInt(chatModal.find('#chat-content').css('margin-bottom'), 10);
var inputGroupHeight = chatModal.find('.input-group').outerHeight();
chatModal.find('#chat-content').css('height', totalHeight - padding - contentMargin - inputGroupHeight);
});
chatModal.find('#chat-with-name').html(username);
chatModal.find('#chat-close-btn').on('click', function() {
@@ -181,7 +197,7 @@ define(['taskbar', 'string', 'sounds'], function(taskbar, S, sounds) {
});
translator.translate('[[modules:chat.user_typing, ' + username + ']]', function(translated) {
chatModal.find('.user-typing').text(translated);
chatModal.find('.user-typing .text').text(translated);
});
@@ -286,7 +302,7 @@ define(['taskbar', 'string', 'sounds'], function(taskbar, S, sounds) {
var time = '<span class="chat-timestamp pull-right timeago" title="' + utils.toISOString(data.timestamp) + '"></span> ';
if (data.fromuid !== chatContent.children().last().attr('data-uid')) {
if (data.fromuid !== chatContent.children('.chat-message').last().attr('data-uid')) {
var userPicture = $('<a href="/user/' + data.fromUser.userslug + '"><img class="chat-user-image" src="' + data.fromUser.picture + '"></a>');
var userName = $('<strong><span class="chat-user"> '+ data.fromUser.username + '</span></strong>');
userName.toggleClass('chat-user-you', isYou);

View File

@@ -1,68 +1,592 @@
"use strict";
/* global define, socket, app */
define(function () {
/*
settings.js 2.0, because version 1:
- saved everything in "config" hash
- was hand-rolled (mm, salmon hand roll)
- Relied on app.config (!!)
This module should:
- Allow you to save to any specified hash
- Rely on jQuery
- Use sockets
- Be more awesome
*/
const DEFAULT_PLUGINS = [
'settings/checkbox',
'settings/textarea',
'settings/select',
'settings/array',
'settings/key'
];
define(function() {
var Settings = {};
var Settings,
onReady = [],
waitingJobs = 0,
helper;
Settings.load = function(hash, formEl, callback) {
socket.emit('admin.settings.get', {
hash: hash
}, function(err, values) {
if (!err) {
$(formEl).deserialize(values);
if (typeof callback === 'function') {
callback();
/*
* Attributes of HTML-tags that get used by default plugins:
* + data-key: the key to save/load the value within configuration-object
* + data-type: highest priority type-definition to determine what kind of element it is or which plugin to hook
* + type: normal priority type-definition
* + data-empty: if 'false' or '0' then values that are assumed as empty turn into null. data-empty of arrays affect
* their child-elements
* + data-trim: if not 'false' or '0' then values will get trimmed as defined by the elements type
* + data-split: if set and the element doesn't belong to any plugin, it's value will get split and joined by its
* value into the input-field
* array-elements:
* + data-split: separator (HTML allowed) between the elements, defaults to ', '
* + data-new: value to insert into new created elements
* + data-attributes: an object to set the attributes of the child HTML-elements. tagName as special key will set
* the tag-name of the child HTML-elements
* key-fields:
* + data-trim: if 'false' or '0' then the value will get saved as string else as object providing following
* properties: ctrl, alt, shift, meta, code, char
* + data-split: separator between different modifiers and the key-code of the value that gets saved
* (only takes effect if trimming)
* + data-short: if not 'false' or '0' then modifier-keys get saved as first uppercase character
* (only takes effect if trimming)
* select:
* + data-options: an array of {"text":"Displayed Text","value":"some_value"}-like objects
*
* The name of the HTML-tag is lowest priority type-definition
*
* Examples-HTML:
No!
<input type="checkbox" data-key="cfg1"></input><br>
Yes!
<input type="checkbox" data-key="cfg2"></input><br>
An array of checkboxes that are selected by default:
<div data-key="cfg3" data-attributes='{"data-type":"checkbox"}' data-new='true'></div><br>
A simple input-field of any common type:
<input type="password" data-key="cfg4"></input><br>
A simple textarea:
<textarea data-key="cfg5"></textarea><br>
Array of textareas:
<div data-key="cfg6" data-attributes='{"data-type":"textarea"}' data-new='Hello Kitty, ahem... World!'></div><br>
2D-Array of numbers that persist even when empty (but not empty rows):
<div data-key="cfg7" data-split="<br>" data-attributes='{"data-type":"array","data-attributes":{"type":"number"}}' data-new='[42,21]'></div><br>
Same with persisting empty rows, but not empty numbers, if no row is given null will get saved:
<div data-key="cfg8" data-split="<br>" data-empty="false" data-attributes='{"data-type":"array","data-empty":true,"data-attributes":{"type":"number","data-empty":false}}' data-new='[42,21]'></div><br>
Array of Key-shortcuts (new: Ctrl+Shift+7):
<div data-key="cfg9" data-attributes='{"data-type":"key"}' data-new='Ctrl+Shift+#55'></div><br>
Array of numbers (new: 42, step: 21):
<div data-key="cfg10" data-attributes='{"data-type":"number","step":21}' data-new='42'></div><br>
Select with dynamic options:
<select data-key="cfg11" data-options='[{"value":"2","text":"2"},{"value":"3","text":"3"}]'></select><br>
Select that loads faster:
<select data-key="cfg12"><br>
<option value="2">2</option>
<option value="3">3</option>
</select>
*
* Matching configuration:
{
cfg1: false,
cfg2: true,
cfg3: [false, false, true],
cfg4: 'hello world',
cfg5: 'some\nlong\ntext',
cfg6: ['some\nlong\ntexts', 'and another one'],
cfg7: [[]],
cfg8: [[]],
cfg9: [],
cfg10: [],
cfg11: 3,
cfg12: 2
}
*/
/**
Returns the hook of given name that matches the given type or element.
@param type The type of the element to get the matching hook for, or the element itself.
@param name The name of the hook.
*/
function getHook(type, name) {
var hook, plugin;
if (typeof type !== 'string') {
type = $(type);
type = type.data('type') || type.attr('type') || type.prop('tagName');
}
plugin = Settings.plugins[type.toLowerCase()];
if (plugin == null) {
return void 0;
}
hook = plugin[name];
if (typeof hook === 'function') {
return hook;
} else {
return null;
}
}
helper = {
/**
@returns Object A deep clone of the given object.
*/
deepClone: function (obj) {
if (typeof obj === 'object') {
return JSON.parse(JSON.stringify(obj));
} else {
return obj;
}
},
/**
Creates a new Element with given data.
@param tagName The tag-name of the element to create.
@param data The attributes to set.
@param text The text to add into the element.
@returns HTMLElement The created element.
*/
createElement: function (tagName, data, text) {
var element = document.createElement(tagName);
for (var k in data) {
element.setAttribute(k, data[k]);
}
if (text) {
element.appendChild(document.createTextNode(text));
}
return element;
},
/**
Calls the init-hook of the given element.
@param element The element to initialize.
*/
initElement: function (element) {
var hook = getHook(element, 'init');
if (hook != null) {
hook.call(Settings, $(element));
}
},
/**
Calls the destruct-hook of the given element.
@param element The element to destruct.
*/
destructElement: function (element) {
var hook = getHook(element, 'destruct');
if (hook != null) {
hook.call(Settings, $(element));
}
},
/**
Creates and initializes a new element.
@param type The type of the new element.
@param tagName The tag-name of the new element.
@param data The data to forward to create-hook or use as attributes.
@returns JQuery The created element.
*/
createElementOfType: function (type, tagName, data) {
var element, hook = getHook(type, 'create');
if (hook != null) {
element = $(hook.call(Settings, type, tagName, data));
} else {
if (data == null) {
data = {};
}
if (type != null) {
data.type = type;
}
element = $(helper.createElement(tagName || 'input', data))
}
element.data('type', type);
helper.initElement(element);
return element;
},
/**
Creates a new Array that contains values of given Array depending on trim and empty.
@param array The array to clean.
@param trim Whether to trim each value if it has a trim-function.
@param empty Whether empty values should get added.
@returns Array The filtered and/or modified Array.
*/
cleanArray: function (array, trim, empty) {
var cleaned = [];
if (!trim && empty) {
return array;
}
for (var i = 0; i < array.length; i++) {
var value = array[i];
if (trim) {
value = value === true ? 1 : value === false ? 0 : typeof value.trim === 'function' ? value.trim() : value;
}
if (empty || (value != null ? value.length : void 0)) {
cleaned.push(value);
}
}
return cleaned;
},
isTrue: function (value) {
return value === 'true' || +value === 1;
},
isFalse: function (value) {
return value === 'false' || +value === 0;
},
/**
Calls the get-hook of the given element and returns its result.
If no hook is specified it gets treated as input-field.
@param element The element of that the value should get read.
@returns Object The value of the element.
*/
readValue: function (element) {
var empty = !helper.isFalse(element.data('empty')),
trim = !helper.isFalse(element.data('trim')),
split = element.data('split'),
hook = getHook(element, 'get'),
value;
if (hook != null) {
return hook.call(Settings, element, trim, empty);
}
if (split != null) {
empty = helper.isTrue(element.data('empty')); // default empty-value is false for arrays
value = element.val();
var array = (value != null ? value.split(split || ',') : void 0) || [];
return helper.cleanArray(array, trim, empty);
} else {
value = element.val();
if (trim && value != null && typeof value.trim === 'function') {
value = value.trim();
}
if (empty || value !== void 0 && (value == null || value.length !== 0)) {
return value;
} else {
return void 0;
}
}
},
/**
Calls the set-hook of the given element.
If no hook is specified it gets treated as input-field.
@param element The JQuery-Object of the element to fill.
@param value The value to set.
*/
fillField: function (element, value) {
var hook = getHook(element, 'set'),
trim = element.data('trim');
trim = trim !== 'false' && +trim !== 0;
if (hook != null) {
return hook.call(Settings, element, value, trim);
}
if (value instanceof Array) {
value = value.join(element.data('split') || (trim ? ', ' : ','));
}
if (trim && value && typeof value.trim === 'function') {
value = value.trim();
if (typeof value.toString === 'function') {
value = value.toString();
}
} else if (value != null) {
if (typeof value.toString === 'function') {
value = value.toString();
}
if (trim) {
value = value.trim();
}
} else {
console.log('[settings] Unable to load settings for hash: ', hash);
value = '';
}
});
};
Settings.save = function(hash, formEl, callback) {
formEl = $(formEl);
if (formEl.length) {
var values = formEl.serializeObject();
// "Fix" checkbox values, so that unchecked options are not omitted
formEl.find('input[type="checkbox"]').each(function(idx, inputEl) {
inputEl = $(inputEl);
if (!inputEl.is(':checked')) {
values[inputEl.attr('id')] = 'off';
if (value !== void 0) {
element.val(value);
}
},
/**
Calls the init-hook and {@link helper.fillField} on each field within wrapper-object.
@param wrapper The wrapper-element to set settings within.
*/
initFields: function (wrapper) {
$('[data-key]', wrapper).each(function (ignored, field) {
field = $(field);
var hook = getHook(field, 'init'),
keyParts = field.data('key').split('.'),
value = Settings.get();
if (hook != null) {
hook.call(Settings, field);
}
for (var i = 0; i < keyParts.length; i++) {
var part = keyParts[i];
if (part && value != null) {
value = value[part];
}
}
helper.fillField(field, value);
});
},
/**
Increases the amount of jobs before settings are ready by given amount.
@param amount The amount of jobs to register.
*/
registerReadyJobs: function (amount) {
return waitingJobs += amount;
},
/**
Decreases the amount of jobs before settings are ready by given amount or 1.
If the amount is less or equal 0 all callbacks registered by {@link helper.whenReady} get called.
@param amount The amount of jobs that finished.
*/
beforeReadyJobsDecreased: function (amount) {
if (amount == null) {
amount = 1;
}
if (waitingJobs > 0) {
waitingJobs -= amount;
if (waitingJobs <= 0) {
for (var i = 0; i < onReady.length; i++) {
onReady[i]();
}
onReady = [];
}
}
},
/**
Calls the given callback when the settings are ready.
@param callback The callback.
*/
whenReady: function (callback) {
if (waitingJobs <= 0) {
callback();
} else {
onReady.push(callback);
}
},
/**
Persists the given settings with given hash.
@param hash The hash to use as settings-id.
@param settings The settings-object to persist.
@param notify Whether to send notification when settings got saved.
@param callback The callback to call when done.
*/
persistSettings: function (hash, settings, notify, callback) {
if (settings != null && settings._settings != null && typeof settings._settings !== 'string') {
settings = helper.deepClone(settings);
settings._settings = JSON.stringify(settings._settings);
}
socket.emit('admin.settings.set', {
hash: hash,
values: values
}, function(err) {
app.alert({
title: 'Settings Saved',
type: 'success',
timeout: 2500
});
values: settings
}, function (err) {
if (notify) {
if (err) {
app.alert({
title: 'Settings Not Saved',
type: 'danger',
message: "NodeBB failed to save the settings.",
timeout: 5000
});
console.log('[settings] Unable to set settings for hash: ', hash);
} else {
app.alert({
title: 'Settings Saved',
type: 'success',
timeout: 2500
});
}
}
if (typeof callback === 'function') {
callback();
callback(err);
}
});
} else {
console.log('[settings] Form not found.');
},
/**
Sets the settings to use to given settings.
@param settings The settings to use.
*/
use: function (settings) {
try {
settings._settings = JSON.parse(settings._settings);
} catch (_error) {}
Settings.cfg = settings;
}
};
Settings = {
helper: helper,
plugins: {},
cfg: {},
/**
Returns the saved settings.
@returns Object The settings.
*/
get: function () {
if (Settings.cfg != null && Settings.cfg._settings !== void 0) {
return Settings.cfg._settings;
}
return Settings.cfg;
},
/**
Registers a new plugin and calls its use-hook.
A plugin is an object containing a types-property to define its default bindings.
A plugin may also provide the following properties of type function with [return-value] (parameters):
use [void] - gets called when the Settings initializes the plugin.
init [void] (element) - gets called on page-load and every time after the create-hook.
; element: The element to initialize.
create [JQuery-Object] (type, tagName, data) - gets called when a new HTML-instance needs to get created.
; type: A string that identifies the plugin itself within this Settings-instance if set as data-type.
; tagName: The tag-name that gets requested.
; data: Additional data, plugin-dependent meaning.
destruct [void] (element) - gets called after a HTML-instance got removed from DOM
; element: The element that got removed.
set [void] (element, value, trim) - gets called when the value of the element should be set to the given value.
; element: The element to set its value.
; value: The value to set.
; trim: Whether the value is considered as trimmed.
get [value] (element, trim, empty) - gets called when the value of the given instance is needed.
; element: The element to get its value.
; trim: Whether the result should be trimmed.
; empty: Whether considered as empty values should get saved too.
All passed elements are JQuery-Objects.
@param service The plugin to register.
@param types The types to bind the plugin to.
*/
registerPlugin: function (service, types) {
if (types == null) {
types = service.types;
} else {
service.types = types;
}
if (typeof service.use === 'function') {
service.use.call(Settings);
}
for (var i = 0; i < types.length; i++) {
var type = types[i].toLowerCase();
if (Settings.plugins[type] == null) {
Settings.plugins[type] = service;
}
}
},
/**
Sets the settings to given ones, resets the fields within given wrapper and saves the settings server-side.
@param hash The hash to use as settings-id.
@param settings The settings to set.
@param wrapper The wrapper-element to find settings within.
@param callback The callback to call when done.
@param notify Whether to send notification when settings got saved.
*/
set: function (hash, settings, wrapper, callback, notify) {
if (notify == null) {
notify = true;
}
helper.whenReady(function () {
helper.use(settings);
helper.initFields(wrapper || 'form');
helper.persistSettings(hash, settings, notify, callback);
});
},
/**
Fetches the settings from server and calls {@link Settings.helper.initFields} once the settings are ready.
@param hash The hash to use as settings-id.
@param wrapper The wrapper-element to set settings within.
@param callback The callback to call when done.
*/
sync: function (hash, wrapper, callback) {
socket.emit('admin.settings.get', {
hash: hash
}, function (err, values) {
if (err) {
console.log('[settings] Unable to load settings for hash: ', hash);
if (typeof callback === 'function') {
callback(err);
}
} else {
helper.whenReady(function () {
helper.use(values);
helper.initFields(wrapper || 'form');
if (typeof callback === 'function') {
callback();
}
});
}
});
},
/**
Reads the settings from fields and saves them server-side.
@param hash The hash to use as settings-id.
@param wrapper The wrapper-element to find settings within.
@param callback The callback to call when done.
@param notify Whether to send notification when settings got saved.
*/
persist: function (hash, wrapper, callback, notify) {
var notSaved = [],
fields = $('[data-key]', wrapper || 'form').toArray();
if (notify == null) {
notify = true;
}
for (var i = 0; i < fields.length; i++) {
var field = $(fields[i]),
value = helper.readValue(field),
parentCfg = Settings.get(),
keyParts = field.data('key').split('.'),
lastKey = keyParts[keyParts.length - 1];
if (keyParts.length > 1) {
for (var j = 0; j < keyParts.length - 1; j++) {
var part = keyParts[j];
if (part && parentCfg != null) {
parentCfg = parentCfg[part];
}
}
}
if (parentCfg != null) {
if (value != null) {
parentCfg[lastKey] = value;
} else {
delete parentCfg[lastKey];
}
} else {
notSaved.push(field.data('key'));
}
}
if (notSaved.length) {
app.alert({
title: 'Attributes Not Saved',
message: "'" + (notSaved.join(', ')) + "' could not be saved. Please contact the plugin-author!",
type: 'danger',
timeout: 5000
});
}
helper.persistSettings(hash, Settings.cfg, notify, callback);
},
load: function (hash, formEl, callback) {
socket.emit('admin.settings.get', {
hash: hash
}, function (err, values) {
if (!err) {
$(formEl).deserialize(values);
if (typeof callback === 'function') {
callback();
}
} else {
console.log('[settings] Unable to load settings for hash: ', hash);
}
});
},
save: function (hash, formEl, callback) {
formEl = $(formEl);
if (formEl.length) {
var values = formEl.serializeObject();
// "Fix" checkbox values, so that unchecked options are not omitted
formEl.find('input[type="checkbox"]').each(function (idx, inputEl) {
inputEl = $(inputEl);
if (!inputEl.is(':checked')) {
values[inputEl.attr('id')] = 'off';
}
});
socket.emit('admin.settings.set', {
hash: hash,
values: values
}, function (err) {
app.alert({
title: 'Settings Saved',
type: 'success',
timeout: 2500
});
if (typeof callback === 'function') {
callback();
}
});
} else {
console.log('[settings] Form not found.');
}
}
};
helper.registerReadyJobs(1);
require(DEFAULT_PLUGINS, function () {
for (var i = 0; i < arguments.length; i++) {
Settings.registerPlugin(arguments[i]);
}
helper.beforeReadyJobsDecreased();
});
return Settings;
});

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