Merge branch 'develop' into activitypub

This commit is contained in:
Barış Soner Uşaklı
2024-08-21 12:57:10 -04:00
108 changed files with 635 additions and 325 deletions

View File

@@ -1,3 +1,81 @@
#### v3.8.4 (2024-08-01)
##### Chores
* up widgets (d1663ac2)
* up widgets (cb4bf9dd)
* up persona (324610de)
* incrementing version number - v3.8.3 (97ce2c44)
* update changelog for v3.8.3 (2a239a79)
* incrementing version number - v3.8.2 (72d91251)
* incrementing version number - v3.8.1 (527326f7)
* incrementing version number - v3.8.0 (e228a6eb)
* incrementing version number - v3.7.5 (6882894d)
* incrementing version number - v3.7.4 (6678744c)
* incrementing version number - v3.7.3 (2d62b6f6)
* incrementing version number - v3.7.2 (cc257e7e)
* incrementing version number - v3.7.1 (712365a5)
* incrementing version number - v3.7.0 (9a6153d7)
* incrementing version number - v3.6.7 (86a17e38)
* incrementing version number - v3.6.6 (6604bf37)
* incrementing version number - v3.6.5 (6c653625)
* incrementing version number - v3.6.4 (83d131b4)
* incrementing version number - v3.6.3 (fc7d2bfd)
* incrementing version number - v3.6.2 (0f577a57)
* incrementing version number - v3.6.1 (f1a69468)
* incrementing version number - v3.6.0 (4cdf85f8)
* incrementing version number - v3.5.3 (ed0e8783)
* incrementing version number - v3.5.2 (52fbb2da)
* incrementing version number - v3.5.1 (4c543488)
* incrementing version number - v3.5.0 (d06fb4f0)
* incrementing version number - v3.4.3 (5c984250)
* incrementing version number - v3.4.2 (3f0dac38)
* incrementing version number - v3.4.1 (01e69574)
* incrementing version number - v3.4.0 (fd9247c5)
* incrementing version number - v3.3.9 (5805e770)
* incrementing version number - v3.3.8 (a5603565)
* incrementing version number - v3.3.7 (b26f1744)
* incrementing version number - v3.3.6 (7fb38792)
* incrementing version number - v3.3.4 (a67f84ea)
* incrementing version number - v3.3.3 (f94d239b)
* incrementing version number - v3.3.2 (ec9dac97)
* incrementing version number - v3.3.1 (151cc68f)
* incrementing version number - v3.3.0 (fc1ad70f)
* incrementing version number - v3.2.3 (b06d3e63)
* incrementing version number - v3.2.2 (758ecfcd)
* incrementing version number - v3.2.1 (20145074)
* incrementing version number - v3.2.0 (9ecac38e)
* incrementing version number - v3.1.7 (0b4e81ab)
* incrementing version number - v3.1.6 (b3a3b130)
* incrementing version number - v3.1.5 (ec19343a)
* incrementing version number - v3.1.4 (2452783c)
* incrementing version number - v3.1.3 (3b4e9d3f)
* incrementing version number - v3.1.2 (40fa3489)
* incrementing version number - v3.1.1 (40250733)
* incrementing version number - v3.1.0 (0cb386bd)
* incrementing version number - v3.0.1 (26f6ea49)
* incrementing version number - v3.0.0 (224e08cd)
##### New Features
* update chat teasers when a new chat starts, closes #12713 (0204f2aa)
* add downvoteVisibility setting, closes #12698 (269fc068)
##### Bug Fixes
* prevent category filter to go to selected cid (10c5cd4c)
* add sizes to maskable so it doesnt crash chrome application tab (ccc86825)
* post preview not working on parent post (a28dd70f)
##### Refactors
* hooks page design (cea18d0c)
* closes #12699, allow boolean false for log-colorize (42ac1f9d)
##### Tests
* test fix maybe (a73f269f)
#### v3.8.3 (2024-06-27)
##### Chores

View File

@@ -14,7 +14,7 @@ services:
- ./install/docker/setup.json:/usr/src/app/setup.json
postgres:
image: postgres:16.3-alpine
image: postgres:16.4-alpine
restart: unless-stopped
environment:
POSTGRES_USER: nodebb

View File

@@ -36,7 +36,7 @@ services:
- redis
postgres:
image: postgres:16.3-alpine
image: postgres:16.4-alpine
restart: unless-stopped
environment:
POSTGRES_USER: nodebb

View File

@@ -30,14 +30,14 @@
"dependencies": {
"@adactive/bootstrap-tagsinput": "0.8.2",
"@fontsource/inter": "5.0.20",
"@fontsource/poppins": "5.0.14",
"@fontsource/poppins": "5.0.15",
"@fortawesome/fontawesome-free": "6.6.0",
"@isaacs/ttlcache": "1.4.1",
"@nodebb/spider-detector": "2.0.3",
"@popperjs/core": "2.11.8",
"ace-builds": "1.35.4",
"ace-builds": "1.35.5",
"archiver": "7.0.1",
"async": "3.2.5",
"async": "3.2.6",
"autoprefixer": "10.4.20",
"bcryptjs": "2.4.3",
"benchpressjs": "2.5.1",
@@ -46,7 +46,7 @@
"bootstrap": "5.3.3",
"bootswatch": "5.3.3",
"chalk": "4.1.2",
"chart.js": "4.4.3",
"chart.js": "4.4.4",
"cheerio": "^1.0.0-rc.12",
"cli-graph": "3.2.2",
"clipboard": "2.0.11",
@@ -65,7 +65,7 @@
"csrf-sync": "4.0.3",
"daemon": "1.1.0",
"diff": "5.2.0",
"esbuild": "0.23.0",
"esbuild": "0.23.1",
"express": "4.19.2",
"express-session": "1.18.0",
"express-useragent": "1.0.15",
@@ -81,7 +81,7 @@
"jquery-deserialize": "2.0.0",
"jquery-form": "4.3.0",
"jquery-serializeobject": "1.0.0",
"jquery-ui": "1.13.3",
"jquery-ui": "1.14.0",
"jsesc": "3.0.2",
"json2csv": "5.0.7",
"jsonwebtoken": "9.0.2",
@@ -102,14 +102,14 @@
"nodebb-plugin-emoji-android": "4.0.0",
"nodebb-plugin-markdown": "13.0.0-pre.9",
"nodebb-plugin-mentions": "4.6.8",
"nodebb-plugin-ntfy": "1.7.5",
"nodebb-plugin-ntfy": "1.7.6",
"nodebb-plugin-spam-be-gone": "2.2.2",
"nodebb-rewards-essentials": "1.0.0",
"nodebb-theme-harmony": "2.0.0-pre.32",
"nodebb-theme-lavender": "7.1.8",
"nodebb-theme-peace": "2.2.6",
"nodebb-theme-persona": "14.0.0-pre.1",
"nodebb-widget-essentials": "7.0.18",
"nodebb-widget-essentials": "7.0.21",
"nodemailer": "6.9.14",
"nprogress": "0.2.0",
"passport": "0.7.0",
@@ -117,7 +117,7 @@
"passport-local": "1.0.0",
"pg": "8.12.0",
"pg-cursor": "2.11.0",
"postcss": "8.4.40",
"postcss": "8.4.41",
"postcss-clean": "1.2.0",
"progress-webpack-plugin": "1.0.16",
"prompt": "1.3.0",
@@ -146,7 +146,7 @@
"validator": "13.12.0",
"webpack": "5.93.0",
"webpack-merge": "6.0.1",
"winston": "3.13.1",
"winston": "3.14.2",
"workerpool": "9.1.3",
"xml": "1.0.1",
"xregexp": "5.1.1",
@@ -155,7 +155,7 @@
},
"devDependencies": {
"@apidevtools/swagger-parser": "10.1.0",
"@commitlint/cli": "19.3.0",
"@commitlint/cli": "19.4.0",
"@commitlint/config-angular": "19.3.0",
"coveralls": "3.1.1",
"eslint": "8.57.0",
@@ -165,8 +165,8 @@
"grunt-contrib-watch": "1.1.0",
"husky": "8.0.3",
"jsdom": "24.1.1",
"lint-staged": "15.2.8",
"mocha": "10.7.0",
"lint-staged": "15.2.9",
"mocha": "10.7.3",
"mocha-lcov-reporter": "1.3.0",
"mockdate": "3.0.5",
"nyc": "17.0.0",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Стая %1",
"chat.chatting-with": "Разговор с",
"chat.placeholder": "Въведете съобщение тук или пуснете снимки и натиснете Ентер за изпращане",
"chat.placeholder.mobile": "Въведете съобщение тук",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Към последните съобщения",
"chat.usernames-and-x-others": "%1 и %2 други",
"chat.chat-with-usernames": "Разговор с %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Konverzace s",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Raum %1",
"chat.chatting-with": "Chatte mit",
"chat.placeholder": "Gebe hier eine Chatnachricht ein, ziehe Bilder per Drag & Drop und drücke die Eingabetaste, um sie zu senden",
"chat.placeholder.mobile": "Hier Chatnachricht eingeben",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Zur neuesten Nachricht gehen",
"chat.usernames-and-x-others": "%1 & %2 andere",
"chat.chat-with-usernames": "Chatte mit %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chatear con",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -4,15 +4,15 @@
"acp-title": "%1 | NodeBB Administraatori kontrollpaneel",
"settings-header-contents": "Sisu",
"changes-saved": "Changes Saved",
"changes-saved": "Muudatused salvestatud",
"changes-saved-message": "Your changes to the NodeBB configuration have been saved.",
"changes-not-saved": "Changes Not Saved",
"changes-not-saved-message": "NodeBB encountered a problem saving your changes. (%1)",
"save-changes": "Save changes",
"changes-not-saved-message": "NodeBB-l tekkis probleem su muudatuste salvestamisel. (%1)",
"save-changes": "Salvesta muudatused",
"min": "Min:",
"max": "Max:",
"view": "View",
"edit": "Edit",
"add": "Add",
"select-icon": "Select Icon"
"view": "Vaata",
"edit": "Muuda",
"add": "Lisa",
"select-icon": "Vali ikoon"
}

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,7 +1,7 @@
{
"uploading-file": "Laen faili üles...",
"select-file-to-upload": "Vali fail mida üles laadida!",
"upload-success": "Fail üles laetud edukalt!",
"upload-success": "Fail edukalt üles laetud!",
"maximum-file-size": "Maksimaalselt %1 kb",
"no-uploads-found": "No uploads found",
"public-uploads-info": "Uploads are public, all visitors can see them.",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "اتاق %1",
"chat.chatting-with": "گفتوگو با",
"chat.placeholder": "پیام چت را اینجا بنویس، عکس‌ها را اینجا درگ و دراپ کن، برای ارسال دکمه Enter را بزن",
"chat.placeholder.mobile": "پیام چت را اینجا بنویس",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "چت با %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Siirry uusimpaan viestiin",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Discussion %1",
"chat.chatting-with": "Discuter avec",
"chat.placeholder": "Écrire vos message ici, glisser & déposer les images, valider sur entrée pour envoyer",
"chat.placeholder.mobile": "Saisir ici le message",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Aller au message le plus récent",
"chat.usernames-and-x-others": "%1 & %2 autres",
"chat.chat-with-usernames": "Discuter avec %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "חדר %1",
"chat.chatting-with": "שוחחו בצ'אט עם",
"chat.placeholder": "כתבו תוכן הודעת הצ'אט כאן, ניתן לגרור ולשחרר כאן תמונות, הקישו אנטר לשליחה.",
"chat.placeholder.mobile": "הקלד הודעת צ'אט כאן",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "עבור להודעה האחרונה",
"chat.usernames-and-x-others": "%1 ו-%2 אחרים",
"chat.chat-with-usernames": "צ'אט עם %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Razgovaraj s",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Csevegés vele",
"chat.placeholder": "Írja be ide a csevegőüzenetet, húzza át a képeket, majd nyomja meg az Enter billentyűt a küldéshez",
"chat.placeholder.mobile": "Írja be ide a csevegő üzenetet",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 és mások",
"chat.chat-with-usernames": "Csevegés a következővel: %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Սենյակ %1",
"chat.chatting-with": "Զրուցել",
"chat.placeholder": "Գրեք հաղորդագրություն այստեղ, տեղադրեք նկարներ, սեղմեք \"enter\" ուղարկելու համար",
"chat.placeholder.mobile": "Գրեք նամակը այստեղ",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Ցույց տալ վերջին նամակը",
"chat.usernames-and-x-others": "%1 և %2 ուրիշները",
"chat.chat-with-usernames": "Գրել %1 - ին",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Berbincang dengan",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Stanza %1",
"chat.chatting-with": "Messaggia con",
"chat.placeholder": "Digita il messaggio di chat qui, trascina le immagini, premi invio per inviare",
"chat.placeholder.mobile": "Digita il messaggio di chat qui",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Vai al messaggio più recente",
"chat.usernames-and-x-others": "%1 & %2 altri",
"chat.chat-with-usernames": "Chatta con %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "とチャット",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "대화방 %1",
"chat.chatting-with": "대화 중",
"chat.placeholder": "여기에 채팅 메시지를 입력하세요. 이미지는 끌어다 놓으세요. 전송하려면 Enter 키를 누르세요.",
"chat.placeholder.mobile": "여기에 채팅 메시지를 입력하세요.",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "가장 최근 메시지로 이동",
"chat.usernames-and-x-others": "%1 및 다른 %2명",
"chat.chat-with-usernames": "%1과 대화",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Sarunāties ar",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Rom %1",
"chat.chatting-with": "Chat med",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -11,7 +11,7 @@
"500.message": "Oeps! Ziet er naar uit dat iets fout ging!",
"400.title": "Foutief verzoek",
"400.message": "It looks like this link is malformed, please double-check and try again.<br/><div class=\"text-sm text-muted\">Return to the <a href='%1/'>home page</a>.</div>",
"register": "Registeren",
"register": "Registreren",
"login": "Login",
"please-log-in": "Aanmelden",
"logout": "Uitloggen",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat met",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Pokój %1",
"chat.chatting-with": "Czatuj z",
"chat.placeholder": "Wpisz tutaj wiadomość, przeciągnij i opuść obrazki, wciśnij enter aby wysłać",
"chat.placeholder.mobile": "Tutaj napisz wiadomość",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 i %2 innych",
"chat.chat-with-usernames": "Czatuj z %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Conversar com",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Conversar com",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Чат с",
"chat.placeholder": "Введите сообщение, перетащите изображения, нажмите enter для отправки",
"chat.placeholder.mobile": "Введите сообщение здесь",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 пользователей и %2 других",
"chat.chat-with-usernames": "Чат с %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chat with",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Konverzácia s",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Klepetajte z",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Bisedo me",
"chat.placeholder": "Shkruani mesazhin e bisedës këtu, tërhiqni dhe lëshoni imazhet, shtypni enter për t'i dërguar",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Соба %1",
"chat.chatting-with": "Ћаскај са",
"chat.placeholder": "Куцајте поруку ћаскања овде, превуците и отпустите слике, притисните enter за слање",
"chat.placeholder.mobile": "Куцајте поруку овде",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Идите на најновију поруку",
"chat.usernames-and-x-others": "%1 & %2 осталих",
"chat.chat-with-usernames": "Ћаскај са %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Chatta med",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "ห้อง %1",
"chat.chatting-with": "คุยกับ",
"chat.placeholder": "พิมพ์ข้อความแชทที่นี้ ลากและปล่อยรูปภาพ กดปุ่ม enter เพื่อส่ง",
"chat.placeholder.mobile": "พิมพ์ข้อความแชทที่นี่",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "ไปที่ข้อความล่าสุด",
"chat.usernames-and-x-others": "%1, %2 และผู้อื่น",
"chat.chat-with-usernames": "แชทกับ %1",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Oda %1",
"chat.chatting-with": "Sohbet",
"chat.placeholder": "Mesajı yazın veya resim sürükleyip bırakın",
"chat.placeholder.mobile": "Sohbet içeriğini buraya giriniz",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "En son yazılan mesaja geri dönün",
"chat.usernames-and-x-others": "%1 & %2 başka kişi",
"chat.chat-with-usernames": "%1 ile sohbet edin",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "Чат з",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -16,5 +16,5 @@
"custom-css.livereload.description": "Bật điều này để buộc tất cả các phiên trên mọi thiết bị trong tài khoản của bạn phải làm mới bất cứ khi nào bạn nhấp vào lưu",
"bsvariables": "_variables.scss",
"bsvariables.description": "Ghi đè các biến bootstrap ở đây. Bạn có thể sử dụng công cụ như <a href=\"https://bootstrap.build/app\">bootstrap.build</a> và dán đầu ra ở đây.<br/>Thay đổi buộc dựng lại và chạy lại.",
"bsvariables.enable": "Enable _variables.scss"
"bsvariables.enable": "Bật _variables.scss"
}

View File

@@ -3,7 +3,7 @@
"checking-for-installed": "Đang kiểm tra các giao diện đã cài đặt...",
"homepage": "Trang chủ",
"select-theme": "Chọn Giao Diện",
"revert-theme": "Revert Theme",
"revert-theme": "Hoàn Nguyên Chủ Đề",
"current-theme": "Giao Diện Hiện Tại",
"no-themes": "Không tìm thấy giao diện đã cài đặt",
"revert-confirm": "Bạn có chắc muốn khôi phục giao diện NodeBB mặc định không?",

View File

@@ -44,8 +44,8 @@
"control-panel": "Điều khiển hệ thống",
"rebuild-and-restart": "Dựng lại &amp; Chạy lại",
"restart": "Chạy lại",
"restart-warning": "Xây dựng lại hoặc Khởi động lại NodeBB của bạn sẽ hủy tất cả các kết nối hiện có trong vài giây.",
"restart-disabled": "Việc xây dựng lại và khởi động lại NodeBB của bạn đã bị vô hiệu hóa vì bạn dường như không chạy nó qua daemon thích hợp.",
"restart-warning": "Dựng lại hay Chạy lại NodeBB của bạn sẽ hủy tất cả các kết nối hiện có trong vài giây.",
"restart-disabled": "Dựng lại và Chạy lại NodeBB của bạn đã bị vô hiệu hóa vì bạn dường như không chạy nó qua daemon thích hợp.",
"maintenance-mode": "Chế Độ Bảo Trì",
"maintenance-mode-title": "Bấm vào đây để thiết lập chế độ bảo trì cho NodeBB",
"dark-mode": "Chế Độ Tối",
@@ -62,7 +62,7 @@
"registered": "Đã đăng ký",
"user-presence": "Người Dùng Có Mặt",
"on-categories": "Trên Danh Sách Chuyên Mục",
"on-categories": "Trên danh sách danh mục",
"reading-posts": "Đọc bài viết",
"browsing-topics": "Duyệt qua chủ đề",
"recent": "Gần đây",

View File

@@ -1,5 +1,5 @@
{
"logger": "Logger",
"logger": "Ghi Nhật Ký",
"logger-settings": "Cài Đặt Ghi Nhật Ký",
"description": "Bật cái này, bạn sẽ nhận nhật ký ở công cụ dòng lệnh của bạn. Nếu có đường dẫn cụ thể, nhật ký sẽ được lưu vào một tệp thay thế. Nhật ký HTTP có lợi để thu thập thống kê ai đó, khi nào và những gì họ làm diễn đàn. Ngoài ghi nhật ký yêu cầu HTTP, chúng ta có thể ghi nhật ký sự kiện socket.io. Ghi nhật ký Socket.io, kết hợp giám sát redis-cli, có thể hữu ích để tìm hiểu bên trong NodeBB.",
"explanation": "Chỉ cần chọn/bỏ chọn cài đặt ghi nhật ký để bật hoặc tắt ghi nhật ký một cách nhanh chóng. Không cần khởi động lại.",

View File

@@ -40,9 +40,9 @@
"alert.upgraded": "Đã Nâng Cấp Plugin",
"alert.installed": "Đã Cài Đặt Plugin",
"alert.uninstalled": "Đã Gỡ Bỏ Plugin",
"alert.activate-success": "Vui lòng xây dựng lại và khởi động lại NodeBB của bạn để kích hoạt hoàn toàn plugin này",
"alert.activate-success": "y dựng lại và chạy lại NodeBB của bạn để kích hoạt plugin này",
"alert.deactivate-success": "Đã hủy kích hoạt plugin thành công",
"alert.upgrade-success": "Vui lòng xây dựng lại và khởi động lại NodeBB của bạn để nâng cấp đầy đủ plugin này.",
"alert.upgrade-success": "y dựng lại và chạy lại NodeBB của bạn để nâng cấp plugin này.",
"alert.install-success": "Đã cài đặt thành công plugin, vui lòng kích hoạt plugin.",
"alert.uninstall-success": "Đã hủy kích hoạt và gỡ cài đặt plugin thành công.",
"alert.suggest-error": "<p>NodeBB không thể tiếp cận trình quản lý gói, hãy tiến hành cài đặt phiên bản mới nhất?</p><div class=\"alert alert-danger\"><strong>Máy chủ trả về (%1)</strong>: %2</div>",
@@ -50,7 +50,7 @@
"alert.incompatible": "<p>Phiên bản NodeBB (v%1) của bạn chỉ được xóa để nâng cấp lên v%2 của plugin này. Vui lòng cập nhật NodeBB của bạn nếu muốn cài đặt phiên bản mới hơn của plugin này.</p>",
"alert.possibly-incompatible": "<div class=\"alert alert-warning\"><p><strong>Không Có Thông Tin Tương Thích</strong></p><p>Plugin này không đưa ra một phiên bản cụ thể để cài đặt với phiên bản NodeBB của bạn. Không đảm bảo khả năng tương thích hoàn toàn và có thể khiến NodeBB của bạn không hoạt động bình thường.</p></div><p>Trường hợp NodeBB không thể hoạt động đúng:</p><pre><code>$ ./nodebb reset plugin=\"%1\"</code></pre><p>Tiếp tục cài đặt phiên bản mới nhất của plugin này?</p>",
"alert.reorder": "Các Plugin Đã Được Sắp Xếp Lại",
"alert.reorder-success": "Vui lòng xây dựng lại và khởi động lại NodeBB của bạn để hoàn tất quá trình.",
"alert.reorder-success": "y dựng lại và chạy lại NodeBB của bạn để hoàn tất quá trình.",
"license.title": "Thông Tin Cấp Phép Plugin",
"license.intro": "Plugin <strong>%1</strong> được cấp phép theo %2. Vui lòng đọc và hiểu các điều khoản cấp phép trước khi kích hoạt plugin này.",

View File

@@ -1,12 +1,12 @@
{
"rewards": "Phần thưởng",
"add-reward": "Add reward",
"add-reward": "Thêm phần thưởng",
"condition-if-users": "Nếu Người Dùng",
"condition-is": "Là:",
"condition-then": "Sau đó:",
"max-claims": "Số lần nhận thưởng có thể nhận được",
"zero-infinite": "Nhập 0 cho vô hạn",
"select-reward": "Select reward",
"select-reward": "Chọn phần thưởng",
"delete": "Xóa",
"enable": "Bật",
"disable": "Tắt",

View File

@@ -1,5 +1,5 @@
{
"widgets": "Widgets",
"widgets": "Tiện ích",
"available": "Tiện ích có sẵn",
"explanation": "Chọn một tiện ích từ menu thả xuống, sau đó kéo và thả nó vào khu vực tiện ích của mẫu ở bên trái.",
"none-installed": "Không tìm thấy tiện ích nào! Kích hoạt plugin tiện ích cần thiết trong bảng điều khiển<a href=\"%1\">plugins</a> .",

View File

@@ -1,10 +1,10 @@
{
"lead": "Một danh sách các số liệu thống kê và thời gian phân phối được hiển thị dưới đây.",
"disclaimer": "Xin lưu ý rằng việc gửi email không được đảm bảo, do bản chất của công nghệ email. Nhiều yếu tố quyết định đến việc liệu một email được gửi đến máy chủ người nhận cuối cùng có được gửi đến hộp thư đến của người dùng hay không, bao gồm danh tiếng của máy chủ, địa chỉ IP nằm trong danh sách đen và liệu DKIM/SPF/DMARC được cấu hình.",
"disclaimer": "Lưu ý việc gửi email không đảm bảo, do bản chất của công nghệ email. Nhiều yếu tố ảnh hưởng đến một email được gửi đến máy chủ người nhận cuối cùng có được gửi đến hộp thư của người dùng hay không, bao gồm danh tiếng máy chủ, địa chỉ IP nằm trong danh sách đen và liệu DKIM/SPF/DMARC được cấu hình.",
"disclaimer-continued": "Gửi thành công nghĩa là tin nhắn được NodeBB gửi thành công và máy chủ người nhận nhận được. Nó không có nghĩa là email đã đến hộp thư đến. Để có kết quả tốt nhất, chúng tôi khuyên bạn nên sử dụng dịch vụ gửi email của bên thứ ba, chẳng hạn như <a href=\"https://sendgrid.com/why-sendgrid/\">SendGrid</a>.",
"user": "Người dùng",
"subscription": "Loại đăng ký",
"subscription": "Loại Đăng Ký",
"last-delivery": "Gửi thành công lần cuối",
"default": "Mặc định hệ thống",
"default-help": "<em>Mặc định hệ thống</em> nghĩa là người dùng không ghi đè lên toàn bộ cài đặt thông báo diễn đàn, hiện là: &quot;<strong>%1</strong>&quot;",

View File

@@ -2,11 +2,11 @@
"manage-uploads": "Quản Lý Tải Lên",
"upload-file": "Tải Lên Tệp",
"filename": "Tên Tệp",
"usage": "Đăng sử dụng",
"usage": "ng Bài Đăng",
"orphaned": "Đơn độc",
"size/filecount": "Kích cỡ/ Số lượng tệp",
"size/filecount": "Kích cỡ/ Số tệp",
"confirm-delete": "Bạn có chắc muốn xóa tệp này không?",
"filecount": "%1 tệp",
"new-folder": "Thư mục mới",
"new-folder": "Thư Mục Mới",
"name-new-folder": "Nhập tên cho thư mục mới"
}

View File

@@ -13,17 +13,17 @@
"token": "Token",
"uid-help-text": "Ghi rõ ID người dùng liên kết với mã truy cập. Nếu ID người dùng là <code>0</code>, nó sẽ là môt mã truy cập <em>cao cấp</em>, có thể giả định danh tính của những người dùng khác dựa trên tham số <code>_uid</code>",
"description": "Mô tả",
"last-seen": "Last seen",
"created": "Created",
"create-token": "Create Token",
"last-seen": "Nhìn thấy lần cuối",
"created": "Đã tạo",
"create-token": "Tạo Token",
"update-token": "Cập Nhật Token",
"master-token": "Master token",
"last-seen-never": "Khóa này chưa bao giờ được dùng.",
"master-token": "Token Chính",
"last-seen-never": "Khóa này chưa bao giờ dùng.",
"no-description": "Không có mô tả cụ thể.",
"actions": "Hành Động",
"edit": "Sửa",
"roll": "Cuộn",
"delete-confirm": "Bạn có chắc chắn muốn xóa mã thông báo này không? Nó sẽ không thể phục hồi được.",
"roll-confirm": "Bạn có chắc chắn muốn tạo lại mã thông báo này không? Mã thông báo cũ sẽ bị thu hồi ngay lập tức và không thể phục hồi được."
"delete-confirm": "Bạn có chắc muốn xóa token này không? Nó không thể phục hồi.",
"roll-confirm": "Bạn có chắc muốn tạo lại token này không? Token cũ sẽ bị thu hồi ngay và không thể phục hồi được."
}

View File

@@ -24,7 +24,7 @@
"logo.upload": "Tải lên",
"logo.url": "Liên kết URL Logo",
"logo.url-placeholder": "URL biểu trưng trang web",
"logo.url-help": "Khi nhấp vào logo, hãy đưa người dùng đến địa chỉ này. Nếu để trống, người dùng sẽ được chuyển đến chỉ mục diễn đàn. <br> Lưu ý: Đây không phải là URL bên ngoài được sử dụng trong email, v.v. Nó được đặt bởi thuộc tính <code>url</code> trong config.json",
"logo.url-help": "Khi nhấp vào logo, đưa người dùng đến địa chỉ này. Nếu để trống, người dùng sẽ được chuyển đến chỉ mục diễn đàn. <br> Lưu ý: Đây không phải là URL bên ngoài được sử dụng trong email, v.v. Nó được đặt bởi thuộc tính <code>url</code> trong config.json",
"logo.alt-text": "Văn Bản Thay Thế",
"log.alt-text-placeholder": "Văn bản thay thế cho khả năng tiếp cận",
"favicon": "Biểu tượng ưa thích",
@@ -32,21 +32,21 @@
"pwa": "Ứng Dụng Web Tiến Bộ",
"touch-icon": "Biểu Tượng Cảm Ứng",
"touch-icon.upload": "Tải lên",
"touch-icon.help": "Kích thước và định dạng được đề xuất: 512x512, chỉ định dạng PNG. Nếu không có biểu tượng cảm ứng nào, NodeBB sẽ quay trở lại sử dụng favicon.",
"maskable-icon": "Biểu tượng có thể che được (Màn Trang Chủ)",
"maskable-icon.help": "Kích thước và định dạng nên là: 512x512, chỉ định dạng PNG. Nếu không có biểu tượng có thể che được nào được chỉ định, NodeBB sẽ trở lại Biểu tượng cảm ứng.",
"touch-icon.help": "Kích c và định dạng được đề xuất: 512x512, chỉ định dạng PNG. Nếu không có biểu tượng cảm ứng nào, NodeBB sẽ quay trở lại sử dụng favicon.",
"maskable-icon": "Biểu tượng có thể che được (Màn Hình Trang Chủ)",
"maskable-icon.help": "Kích thước và định dạng nên là: 512x512, chỉ định dạng PNG. Nếu không có biểu tượng có thể che được nào được chỉ định, NodeBB sẽ trở lại Biểu Tượng Chạm.",
"outgoing-links": "Liên Kết Đi",
"outgoing-links.warning-page": "Sử Dụng Trang Cảnh Báo Liên Kết Đi",
"search": "Tìm kiếm",
"search-default-in": "Tìm kiếm trong",
"search-default-in-quick": "Tìm kiếm nhanh trong",
"search-default-sort-by": "Sắp xếp theo",
"search-default-in": "Tìm Trong",
"search-default-in-quick": "Tìm Nhanh Trong",
"search-default-sort-by": "Xếp theo",
"outgoing-links.whitelist": "Các tên miền trong danh sách trắng sẽ bỏ qua trang cảnh báo",
"site-colors": "Dữ Liệu Mô Tả Màu Trang",
"theme-color": "Màu Giao Diện",
"background-color": "Màu Nền",
"background-color-help": "Màu được sử dụng cho nền màn hình khởi động khi trang web được cài đặt làm PWA",
"undo-timeout": "Hoàn tác thời gian chờ",
"undo-timeout-help": "Một số thao tác như chuyển chủ đề sẽ cho phép người kiểm duyệt hoàn tác hành động của họ trong một khung thời gian nhất định. Đặt thành 0 để tắt hoàn toàn hoàn tác.",
"undo-timeout": "Thời Gian Chờ Hoàn Tác",
"undo-timeout-help": "Một số thao tác như chuyển chủ đề sẽ cho phép mod hoàn tác hành động của họ trong khung giờ nhất định. Đặt thành 0 để tắt hoàn toàn hoàn tác.",
"topic-tools": "Công cụ chủ đề"
}

View File

@@ -1,8 +1,8 @@
{
"home-page": "Trang Chủ",
"description": "Chọn trang hiển thị khi người dùng được chuyển hướng đến URL gốc diễn đàn của bạn.",
"description": "Chọn trang hiển thị khi người dùng chuyển hướng đến URL gốc diễn đàn của bạn.",
"home-page-route": "Liên Kết Trang Chủ",
"custom-route": "Tùy Chỉnh Liên Kết",
"allow-user-home-pages": "Cho Phép Trang Chủ Người Dùng",
"home-page-title": "Tiêu đề của trang chủ (mặc định là \"Trang chủ\")"
"home-page-title": "Tiêu đề trang chủ (mặc định là \"Trang chủ\")"
}

View File

@@ -2,5 +2,5 @@
"language-settings": "Cài Đặt Ngôn Ngữ",
"description": "Ngôn ngữ mặc định là cài đặt ngôn ngữ cho tất cả người dùng diễn đàn của bạn. <br />Người dùng cá nhân có thể thay đổi ngôn ngữ họ thích trong cài đặt tài khoản",
"default-language": "Ngôn Ngữ Mặc Định",
"auto-detect": "Tự Động Phát Hiện Cài Đặt Ngôn Ngữ Cho Khách"
"auto-detect": "Tự Phát Hiện Cài Đặt Ngôn Ngữ Cho Khách"
}

View File

@@ -5,11 +5,11 @@
"upvote-visibility": "Khả năng hiển thị số ủng hộ",
"upvote-visibility-all": "Mọi người có thể xem số ủng hộ",
"upvote-visibility-loggedin": "Chỉ người dùng đã đăng nhập mới có thể xem số ủng hộ",
"upvote-visibility-privileged": "Chỉ những người dùng đặc quyền như quản trị viên và người kiểm duyệt mới có thể số ủng hộ",
"upvote-visibility-privileged": "Chỉ những ai có đặc quyền như admin và mod được xem số ủng hộ",
"downvote-visibility": "Khả năng hiển thị số phản đối",
"downvote-visibility-all": "Mọi người có thể xem số phản đối",
"downvote-visibility-loggedin": "Chỉ người dùng đã đăng nhập có thể xem số phản đối",
"downvote-visibility-privileged": "Chỉ người dùng đặc quyền như quản trị viên hoặc người điều hành có thể xem số phản đối",
"downvote-visibility-loggedin": "Chỉ ai đã đăng nhập được xem số phản đối",
"downvote-visibility-privileged": "Chỉ người dùng đặc quyền như admin hoặc mod có thể xem số phản đối",
"thresholds": "Ngưỡng hoạt động",
"min-rep-upvote": "Uy tín tối thiểu để ủng hộ bài đăng",
"upvotes-per-day": "Số phiếu ủng hộ mỗi ngày (đặt là 0 để không giới hạn)",

View File

@@ -32,18 +32,18 @@
"session-duration": "Thời lượng phiên nếu \"Ghi nhớ tôi\" không được chọn (giây)",
"session-duration-help": "Theo mặc định — hoặc nếu đặt thành <code>0</code> — người dùng sẽ duy trì trạng thái đăng nhập trong suốt thời gian của phiên (VD: cửa sổ/tab trình duyệt vẫn mở trong bao lâu). Đặt giá trị này để vô hiệu hóa rõ ràng phiên sau số giây đã chỉ định.",
"online-cutoff": "Số phút sau khi người dùng được coi là không hoạt động",
"online-cutoff-help": "Nếu người dùng không thao tác trong khoảng thời gian này, được coi là không hoạt động và không nhận được cập nhật theo thời gian thực.",
"online-cutoff-help": "Nếu người dùng không thao tác trong thời gian này, sẽ coi là không hoạt động và không cập nhật thời gian thực.",
"registration": "Đăng Ký Người Dùng",
"registration-type": "Loại Đăng Ký",
"registration-approval-type": "Loại Xét Duyệt Đăng Ký",
"registration-type": "Kiểu Đăng Ký",
"registration-approval-type": "Kiểu Xét Duyệt Đăng Ký",
"registration-type.normal": "Bình thường",
"registration-type.admin-approval": "Quản Trị Viên Phê Duyệt",
"registration-type.admin-approval-ip": "Quản Trị Viên Phê Duyệt cho IP",
"registration-type.admin-approval": "Admin Phê Duyệt",
"registration-type.admin-approval-ip": "Amin Duyệt IP",
"registration-type.invite-only": "Chỉ Mời",
"registration-type.admin-invite-only": "Chỉ Quản Trị Viên Mời",
"registration-type.disabled": "Không đăng ký",
"registration-type.help": "Bình thường - Người dùng có thể đăng ký từ trang /register.<br/>\nChỉ mời - Người dùng có thể mời những người khác từ trang <a href=\"%1/users\" target=\"_blank\">người dùng</a>.<br/>\nChỉ Quản Trị Viên mời - Chỉ quản trị viên mới có thể mời người khác từ trang <a href=\"%1/users\" target=\"_blank\">người dùng</a> và <a href=\"%1/admin/manage/users\">admin/manage/users</a>.<br/>\nKhông đăng ký - Không đăng ký người dùng.<br/>",
"registration-approval-type.help": "Bình thường - Người dùng được đăng ký ngay lập tức.<br/>\nPhê duyệt của quản trị viên - Đăng ký người dùng được đặt trong <a href=\"%1/admin/manage/registration\"> xếp hàng phê duyệt </a> cho quản trị viên.<br/>\nPhê duyệt của quản trị viên cho các IP - Bình thường cho người dùng mới, Phê duyệt quản trị cho các địa chỉ IP đã có tài khoản.<br/>",
"registration-type.admin-invite-only": "Chỉ Admin Mời",
"registration-type.disabled": "Không đăng ký",
"registration-type.help": "Bình Thường - Người dùng có thể đăng ký từ trang /register.<br/>\nChỉ Mời - Người dùng có thể mời những người khác từ trang <a href=\"%1/users\" target=\"_blank\">người dùng</a>.<br/>\nChỉ Admin Mời - Chỉ quản trị viên mới có thể mời người khác từ trang <a href=\"%1/users\" target=\"_blank\">người dùng</a> và <a href=\"%1/admin/manage/users\">admin/manage/users</a>.<br/>\nKhông đăng ký - Không đăng ký người dùng.<br/>",
"registration-approval-type.help": "Bình thường - Người dùng được đăng ký ngay lập tức.<br/>\nAdmin phê duyệt - Đăng ký người dùng được đặt trong <a href=\"%1/admin/manage/registration\"> hàng phê duyệt </a> cho quản trị viên.<br/>\nAdmin phê duyệt IP - Bình thường cho người mới, Admin phê duyệt IP đã có tài khoản.<br/>",
"registration-queue-auto-approve-time": "Thời Gian Xét Duyệt Tự Động",
"registration-queue-auto-approve-time-help": "Giờ trước khi người dùng được xét duyệt tự động. 0 để tắt.",
"registration-queue-show-average-time": "Hiện thời gian xét duyệt cho người dùng mới biết",
@@ -58,7 +58,7 @@
"min-password-strength": "Độ Mạnh Mật Khẩu Tối Thiểu",
"max-about-me-length": "Độ Dài Tối Đa Giới Thiệu Bản Thân",
"terms-of-use": "Điều Khoản Sử Dụng Diễn Đàn <small>(Để trống để tắt)</small>",
"user-search": "Tìm Kiếm Người Dùng",
"user-search": "Tìm Người Dùng",
"user-search-results-per-page": "Số lượng người dùng hiển thị trong kết quả tìm kiếm",
"default-user-settings": "Cài Đặt Người Dùng Mặc Định",
"show-email": "Hiển thị email",
@@ -80,7 +80,7 @@
"default-notification-settings": "Cài đặt thông báo mặc định",
"categoryWatchState": "Trạng thái xem chuyên mục mặc định",
"categoryWatchState.tracking": "Theo dõi",
"categoryWatchState.notwatching": "Không Xem",
"categoryWatchState.notwatching": "Chưa Xem",
"categoryWatchState.ignoring": "Bỏ Qua",
"restrictions-new": "Hạn chế người dùng mới",
"restrictions.rep-threshold": "Ngưỡng uy tín trước khi những hạn chế này được dỡ bỏ",

View File

@@ -11,7 +11,7 @@
"ignore": "Bỏ qua",
"watching": "Đang xem",
"tracking": "Theo dõi",
"not-watching": "Không xem",
"not-watching": "Chưa Xem",
"ignoring": "Bỏ qua",
"watching.description": "Thông báo tôi chủ đề mới.<br/>Hiển thị chủ đề chưa đọc và gần đây",
"tracking.description": "Hiển thị chủ đề chưa đọc và gần đây",
@@ -21,6 +21,6 @@
"tracking.message": "Bạn hiện đang theo dõi thông tin cập nhật từ danh mục này và tất cả các danh mục phụ",
"notwatching.message": "Bạn không xem cập nhật từ danh mục này và tất cả các danh mục phụ",
"ignoring.message": "Bây giờ bạn đang bỏ qua các cập nhật từ danh mục này và tất cả các danh mục phụ",
"watched-categories": "Chuyên mục đã xem",
"watched-categories": "Danh mục đã xem",
"x-more-categories": "%1 chuyên mục khác"
}

View File

@@ -3,8 +3,8 @@
"password-reset-requested": "Yêu cầu đặt lại mật khẩu!",
"welcome-to": "Chào mừng đến với %1",
"invite": "Lời mời từ %1",
"greeting-no-name": "Xin chào",
"greeting-with-name": "Xin chào %1",
"greeting-no-name": "Chào",
"greeting-with-name": "Chào %1",
"email.verify-your-email.subject": "Vui lòng xác thực tài khoản của bạn",
"email.verify.text1": "Bạn đã yêu cầu chúng tôi thay đổi hoặc xác nhận địa chỉ email của bạn",
"email.verify.text2": "Vì lý do bảo mật, chúng tôi chỉ thay đổi hoặc xác nhận địa chỉ email trong hồ sơ khi quyền sở hữu của nó đã được xác nhận qua email. <strong>Nếu bạn không yêu cầu điều này, bạn không cần thực hiện hành động nào.</strong>",
@@ -36,8 +36,8 @@
"digest.title.day": "Thông Báo Hàng Ngày Của Bạn",
"digest.title.week": "Thông Báo Hàng Tuần Của Bạn",
"digest.title.month": "Thông Báo Hàng Tháng Của Bạn",
"notif.chat.new-message-from-user": "New message from \"%1\"",
"notif.chat.new-message-from-user-in-room": "New message from %1 in room %2",
"notif.chat.new-message-from-user": "Tin nhắn mới từ \"%1\"",
"notif.chat.new-message-from-user-in-room": "Tin nhắn mới từ %1 trong phòng %2",
"notif.chat.cta": "Nhấn vào đây để tiếp tục cuộc hội thoại",
"notif.chat.unsub.info": "Thông báo trò chuyện này đã được gửi cho bạn dựa theo cài đặt đăng ký của bạn.",
"notif.post.unsub.info": "Thông báo bài viết này được gửi cho bạn dựa tên thiết lập nhận thông báo của bạn",
@@ -57,5 +57,5 @@
"banned.text1": "Người dùng %1 đã bị cấm khỏi %2",
"banned.text2": "Lệnh cấm sẽ kéo dài đến %1.",
"banned.text3": "Đây là lý do tại sao bạn bị cấm:",
"closing": "Xin cảm ơn!"
"closing": "Cảm ơn!"
}

View File

@@ -91,17 +91,17 @@
"category-not-selected": "Danh mục không được chọn.",
"too-many-posts": "Bạn chỉ có đăng bài mới mỗi %1 giây - vui lòng đợi để tiếp tục đăng bài.",
"too-many-posts-newbie": "Là người dùng mới, bạn chỉ có thể đăng %1 giây một lần cho đến khi bạn đạt được %2 danh tiếng - vui lòng đợi trước khi đăng lại",
"too-many-posts-newbie-minutes": "Là người dùng mới, bạn chỉ có thể đăng bài %1 phút một lần cho đến khi bạn đạt được %2 danh tiếng - vui lòng đợi trước khi đăng lại",
"already-posting": "You are already posting",
"too-many-posts-newbie-minutes": "Là người dùng mới, bạn chỉ được đăng bài %1 phút một lần cho đến khi bạn đạt được %2 danh tiếng - vui lòng đợi trước khi đăng lại",
"already-posting": "Bạn đã đăng rồi",
"tag-too-short": "Vui lòng nhập tag dài hơn. Tag phải có tối thiểu %1 ký tự.",
"tag-too-long": "Vui lòng nhập tag ngắn hơn. Tag chỉ có thể có tối đa %1 ký tự.",
"tag-not-allowed": "Thẻ không được phép",
"tag-not-allowed": "Thẻ không cho phép",
"not-enough-tags": "Không đủ thẻ. Chủ đề phải có ít nhất %1 thẻ.",
"too-many-tags": "Quá nhiều thẻ. Chủ đề không thể nhiều hơn %1 thẻ.",
"cant-use-system-tag": "Bạn không thể dùng thẻ hệ thống này.",
"cant-remove-system-tag": "Bạn không thể xóa thẻ hệ thống này.",
"still-uploading": "Vui lòng đợi quá trình tải lên hoàn tất.",
"file-too-big": "Kích thước tệp cho phép tối đa là %1 kB - vui lòng tải lên một tệp nhỏ hơn",
"file-too-big": "Kích thước tối đa là %1 kB - vui lòng tải lên một tệp nhỏ hơn",
"guest-upload-disabled": "Tải lên của khách đã bị tắt",
"cors-error": "Không thể tải lên hình ảnh do CORS bị cấu hình sai",
"upload-ratelimit-reached": "Bạn đã tải lên quá nhiều tệp cùng một lúc. Vui lòng thử lại sau.",
@@ -168,12 +168,12 @@
"cant-remove-users-from-chat-room": "Không thể xóa người dùng khỏi phòng trò chuyện.",
"chat-room-name-too-long": "Tên phòng trò chuyện quá dài. Tên không được dài hơn %1 ký tự.",
"already-voting-for-this-post": "Bạn đã bỏ phiếu cho bài viết này",
"reputation-system-disabled": "Hệ thống đánh giá uy tính đã bị vô hiệu hóa.",
"reputation-system-disabled": "Hệ thống đánh giá uy tính đã tắt.",
"downvoting-disabled": "Phản đối đã bị tắt",
"not-enough-reputation-to-chat": "Bạn cần %1 uy tín để trò chuyện",
"not-enough-reputation-to-upvote": "Bạn cần %1 uy tín để ủng hộ",
"not-enough-reputation-to-downvote": "Bạn cần %1 uy tín để phản đối",
"not-enough-reputation-to-post-links": "You need %1 reputation to post links",
"not-enough-reputation-to-post-links": "Bạn cần %1 uy tín để đăng liên kết",
"not-enough-reputation-to-flag": "Bạn cần %1 uy tín để gắn cờ bài đăng này",
"not-enough-reputation-min-rep-website": "Bạn cần %1 uy tín để thêm một trang web",
"not-enough-reputation-min-rep-aboutme": "Bạn cần %1 uy tín để thêm thông tin bản thân",
@@ -184,15 +184,15 @@
"user-already-flagged": "Bạn đã gắn cờ người dùng này",
"post-flagged-too-many-times": "Bài đăng này đã bị người khác gắn cờ",
"user-flagged-too-many-times": "Người dùng này đã bị người khác gắn cờ",
"too-many-post-flags-per-day": "Bạn chỉ có thể gắn cờ %1 bài đăng mỗi ngày",
"too-many-user-flags-per-day": "Bạn chỉ có thể gắn cờ %1 người dùng mỗi ngày",
"cant-flag-privileged": "Bạn không có quyền gắn cờ hồ sơ hay nội dung của người dùng đặc quyền (người kiểm duyệt/người điều hành chung/quản trị viên)",
"too-many-post-flags-per-day": "Bạn chỉ được gắn cờ %1 bài đăng mỗi ngày",
"too-many-user-flags-per-day": "Bạn chỉ được gắn cờ %1 người dùng mỗi ngày",
"cant-flag-privileged": "Bạn không có quyền gắn cờ hồ sơ hay nội dung của người dùng đặc quyền (mod/người điều hành chung/admin)",
"cant-locate-flag-report": "Không thể định vị báo cáo cờ",
"self-vote": "Bạn không thể tự bầu cho bài đăng của mình",
"too-many-upvotes-today": "Bạn chỉ có thể ủng hộ %1 lần một ngày",
"too-many-upvotes-today-user": "Bạn chỉ có thể ủng hộ người dùng %1 lần một ngày",
"too-many-upvotes-today-user": "Bạn chỉ được ủng hộ người dùng %1 lần một ngày",
"too-many-downvotes-today": "Bạn chỉ có thể phản đối %1 lần một ngày",
"too-many-downvotes-today-user": "Bạn chỉ có thể phản đối người dùng %1 lần một ngày",
"too-many-downvotes-today-user": "Bạn chỉ được phản đối người dùng %1 lần một ngày",
"reload-failed": "NodeBB gặp lỗi trong khi tải lại: \"%1\". NodeBB sẽ tiếp tục hoạt động với dữ liệu trước đó, tuy nhiên bạn nên tháo gỡ những gì bạn vừa thực hiện trước khi tải lại.",
"registration-error": "Lỗi Đăng Ký",
"parse-error": "Đã xảy ra lỗi khi phân tích phản hồi của máy chủ",
@@ -213,9 +213,9 @@
"session-mismatch-text": "Có vẻ như phiên đăng nhập của bạn không còn khớp với máy chủ. Vui lòng làm mới trang này.",
"no-topics-selected": "Không có chủ đề nào đang được chọn!",
"cant-move-to-same-topic": "Bạn không thể di chuyển bài viết vào cùng chủ đề hiện tại!",
"cant-move-topic-to-same-category": "Không thể di chuyển chủ đề sang cùng chuyên mục!",
"cannot-block-self": "Bạn không thể tự khóa tài khoản của bạn!",
"cannot-block-privileged": "Bạn không thể khóa quản trị viên hay người điều hành chung.",
"cant-move-topic-to-same-category": "Không thể di chuyển chủ đề đến cùng danh mục!",
"cannot-block-self": "Bạn không thể tự khóa bạn!",
"cannot-block-privileged": "Bạn không thể admin hay người điều hành chung.",
"cannot-block-guest": "Khách không thể chặn người dùng khác",
"already-blocked": "Người dùng này đã bị chặn",
"already-unblocked": "Người dùng này đã được bỏ chặn",

View File

@@ -5,7 +5,7 @@
"first-reported": "Được báo cáo đầu tiên",
"no-flags": "Hoan hô! Không tìm thấy cờ.",
"x-flags-found": "%1 cờ tìm thấy.",
"assignee": "Người được ủy nhiệm",
"assignee": "y nhiệm",
"update": "Cập nhật",
"updated": "Đã cập nhật",
"resolved": "Đã Xử Lý",
@@ -19,14 +19,14 @@
"filter-active": "Có một hoặc nhiều bộ lọc đang hoạt động trong danh sách cờ này",
"filter-reset": "Xóa Bộ Lọc",
"filters": "Tùy Chọn Bộ Lọc",
"filter-reporterId": "Phóng viên",
"filter-targetUid": "Reportee",
"filter-reporterId": "Báo cáo viên",
"filter-targetUid": "Người cáo cáo",
"filter-type": "Loại Cờ",
"filter-type-all": "Tất Cả Nội Dung",
"filter-type-post": "Bài viết",
"filter-type-user": "Người dùng",
"filter-state": "Trạng thái",
"filter-assignee": "Assignee",
"filter-assignee": "Ủy nhiệm",
"filter-cid": "Chuyên mục",
"filter-quick-mine": "Được giao cho tôi",
"filter-cid-all": "Tất cả chuyên mục",

View File

@@ -144,7 +144,7 @@
"copied": "Đã sao chép",
"user-search-prompt": "Nhập để tìm kiếm thành viên",
"hidden": "Ẩn",
"sort": "Sort",
"sort": "Xếp",
"actions": "Hành Động",
"rss-feed": "Nguồn RSS",
"skip-to-content": "Bỏ qua nội dung"

View File

@@ -1,12 +1,13 @@
{
"chat.room-id": "Room %1",
"chat.room-id": "Phòng %1",
"chat.chatting-with": "Trò chuyện với",
"chat.placeholder": "Nhập tin nhắn trò chuyện tại đây, kéo và thả hình ảnh, nhấn enter để gửi",
"chat.placeholder.mobile": "Nhập tin nhắn trò chuyện tại đây",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Đi đến tin nhắn gần đây nhất",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.usernames-and-x-others": "%1 & %2 khác",
"chat.chat-with-usernames": "Trò chuyện với %1",
"chat.chat-with-usernames-and-x-others": "Chat with %1 & %2 others",
"chat.chat-with-usernames-and-x-others": "Trò chuyện với %1 & %2 khác",
"chat.send": "Gửi",
"chat.no-active": "Bạn không có cuộc trò chuyện đang hoạt động nào.",
"chat.user-typing-1": "<strong>%1</strong> đang viết ...",
@@ -54,7 +55,7 @@
"chat.select-groups": "Chọn Nhóm",
"chat.add-user-help": "Tìm người dùng ở đây. Người dùng được chọn sẽ được thêm vào trò chuyện. Người dùng mới vào sẽ không thấy tin nhắn trò chuyện được đăng trước khi họ được thêm vào. Chỉ chủ phòng (<i class=\"fa fa-star text-warning\"></i>) được xóa người dùng khỏi phòng trò chuyện.",
"chat.confirm-chat-with-dnd-user": "Người dùng này đã đặt trạng thái của họ thành DnD (Không làm phiền). Bạn vẫn muốn trò chuyện với họ?",
"chat.room-name-optional": "Room Name (Optional)",
"chat.room-name-optional": "Tên Phòng (Tùy Chọn)",
"chat.rename-room": "Đổi Tên Phòng",
"chat.rename-placeholder": "Nhập tên phòng của bạn ở đây",
"chat.rename-help": "Đẳt tên phòng ở đây, tất cả những người tham gia phòng này có thể xem.",

View File

@@ -47,11 +47,11 @@
"account/latest-posts": "Bài viết mới nhất do %1",
"account/topics": "Chủ đề được tạo bởi %1",
"account/groups": "Nhóm của %1",
"account/watched-categories": "Chuyên Mục Đã Xem Của %1",
"account/watched-categories": "Danh Mục Đã Xem Của %1",
"account/watched-tags": "%1's Thẻ Đã Xem",
"account/bookmarks": "Bài Đăng Được Đánh Dấu Trang Của %1",
"account/settings": "Cài Đặt Người Dùng",
"account/settings-of": "Changing settings of %1",
"account/settings-of": "Thay đổi cài đặt của %1",
"account/watched": "Chủ đề đã được %1 xem",
"account/ignored": "Các chủ đề bị bỏ qua bởi %1",
"account/upvoted": "Bài đăng được %1 ủng hộ",

View File

@@ -8,7 +8,7 @@
"public-intro": "Nếu bạn có bất kỳ bài đăng nào được xếp hàng đợi, chúng sẽ được hiển thị ở đây.",
"public-description": "Diễn đàn này được cấu hình tự động xếp hàng các bài đăng từ tài khoản mới, chờ người điều hành phê duyệt.<br />Nếu bạn đã xếp hàng các bài đăng đợi phê duyệt, bạn sẽ có thể xem chúng ở đây.",
"user": "Người dùng",
"when": "When",
"when": "Khi",
"category": "Chuyên mục",
"title": "Tiêu đề",
"content": "Nội dung",

View File

@@ -7,5 +7,5 @@
"alltime": "Mọi Lúc",
"no-recent-topics": "Không có chủ đề gần đây.",
"no-popular-topics": "Không có chủ đề nào phổ biến.",
"load-new-posts": "Load new posts"
"load-new-posts": "Tải bài đăng mới"
}

View File

@@ -13,7 +13,7 @@
"password-placeholder": "Nhập mật khẩu",
"confirm-password": "Xác Nhận Mật Khẩu",
"confirm-password-placeholder": "Xác Nhận Mật Khẩu",
"register-now-button": "Đăng ký ngay",
"register-now-button": "Đăng Ký Ngay",
"alternative-registration": "Đăng Ký Thay Thế",
"terms-of-use": "Điều khoản sử dụng",
"agree-to-terms-of-use": "Tôi đồng ý với các điều khoản sử dụng",

View File

@@ -28,10 +28,10 @@
"posted-by-usernames": "Đăng bởi: %1",
"type-a-username": "Nhập tên người dùng",
"search-child-categories": "Tìm kiếm chuyên mục con",
"has-tags": "Có thẻ bên trong",
"has-tags": "Có thẻ",
"reply-count": "Số lượt trả lời",
"replies": "Replies",
"replies-atleast-count": "Replies: At least %1",
"replies": "Trả lời",
"replies-atleast-count": "Trả lời: Ít nhất %1",
"replies-atmost-count": "Trả lời: Nhiều nhất là %1",
"at-least": "Tối thiểu",
"at-most": "Nhiều nhất",

View File

@@ -1,11 +1,11 @@
{
"sign-in-with-twitter": "Đăng nhập bằng Twitter",
"sign-in-with-twitter": "Đăng nhập với Twitter",
"sign-up-with-twitter": "Đăng ký với Twitter",
"sign-in-with-github": "Đăng nhập bằng Github",
"sign-up-with-github": "Đăng ký với Github",
"sign-in-with-google": "Đăng nhập bằng Google",
"sign-up-with-google": "Đăng ký với Google",
"log-in-with-facebook": "Đăng nhập bằng Facebook",
"log-in-with-facebook": "Đăng nhập với Facebook",
"continue-with-facebook": "Tiếp tục với Facebook",
"sign-in-with-linkedin": "Đăng nhập với LinkedIn",
"sign-up-with-linkedin": "Đăng ký với LinkedIn"

View File

@@ -1,5 +1,5 @@
{
"all-tags": "Tất cả các thẻ",
"all-tags": "Tất cả thẻ",
"no-tag-topics": "Không có bài viết nào với thẻ này.",
"no-tags-found": "Không tìm thấy thẻ nào",
"tags": "Thẻ",
@@ -8,8 +8,8 @@
"no-tags": "Chưa có thẻ nào.",
"select-tags": "Chọn Thẻ",
"tag-whitelist": "Danh Sách Trắng Thẻ",
"watching": "Watching",
"not-watching": "Not Watching",
"watching": "Đang xem",
"not-watching": "Chưa xem",
"watching.description": "Thông báo tôi chủ đề mới.",
"not-watching.description": "Không thông báo tôi chủ đề mới.",
"following-tag.message": "Bây giờ bạn sẽ nhận được thông báo khi ai đó đăng chủ đề có thẻ này.",

View File

@@ -88,7 +88,7 @@
"unwatch.title": "Ngừng xem chủ đề này",
"share-this-post": "Chia sẻ bài viết này",
"watching": "Đang xem",
"not-watching": "Không Xem",
"not-watching": "Chưa Xem",
"ignoring": "Bỏ qua",
"watching.description": "Thông báo cho tôi về trả lời mới. <br/>Hiển thị chủ đề chưa đọc",
"not-watching.description": "Không thông báo tôi các trả lời mới. <br/>Hiển thị mục chưa đọc nếu chuyên mục bị bỏ qua.",
@@ -163,11 +163,11 @@
"composer.discard": "Huỷ bỏ",
"composer.submit": "Gửi",
"composer.additional-options": "Tùy chọn bổ sung",
"composer.post-later": "Post Later",
"composer.post-later": "Đăng Sau",
"composer.schedule": "Lên lịch",
"composer.replying-to": "Đang trả lời %1",
"composer.new-topic": "Chủ đề mới",
"composer.editing-in": "Editing post in %1",
"composer.editing-in": "Đang sửa bài đăng trong %1",
"composer.uploading": "đang tải lên...",
"composer.thumb-url-label": "Dán URL hình mô tả chủ đề",
"composer.thumb-title": "Thêm ảnh mô tả cho chủ đề này",
@@ -191,10 +191,10 @@
"stale.warning": "Chủ đề bạn đang trả lời đã khá cũ. Bạn có muốn tạo chủ đề mới, và liên kết với chủ đề hiện tại trong bài viết trả lời của bạn?",
"stale.create": "Tạo chủ đề mới",
"stale.reply-anyway": "Trả lời chủ đề này",
"link-back": "Re: [%1](%2)",
"diffs.title": "Lịch schỉnh sửa bài viết",
"diffs.description": "Bài viết này có <strong>%1</strong> sửa đổi. Nhấp vào một trong các bản sửa đổi bên dưới để xem nội dung bài đăng tại thời điểm đó.",
"diffs.no-revisions-description": "Bài viết này có <strong>%1</strong> sửa đổi",
"link-back": "Trả lời: [%1](%2)",
"diffs.title": "Lịch SSửa Bài",
"diffs.description": "Bài này có <strong>%1</strong> sửa đổi. Bấm vào một trong các bản sửa đổi bên dưới để xem nội dung bài tại thời điểm đó.",
"diffs.no-revisions-description": "Bài này có <strong>%1</strong> sửa đổi",
"diffs.current-revision": "bản sửa đổi hiện tại",
"diffs.original-revision": "bản sửa đổi gốc",
"diffs.restore": "Khôi phục bản sửa đổi này",

View File

@@ -10,7 +10,7 @@
"topics-marked-as-read.success": "Chủ đề được đánh dấu đã đọc",
"all-topics": "Tất Cả Chủ Đề",
"new-topics": "Chủ đề mới",
"watched-topics": "Chủ đđã xem",
"unreplied-topics": "Chủ Đề Chưa Trả Lời",
"watched-topics": "Chủ ĐĐã Xem",
"unreplied-topics": "Chủ Đề Chưa Trả Lời",
"multiple-categories-selected": "Chọn Nhiều"
}

View File

@@ -4,6 +4,6 @@
"upload-success": "Tải tệp lên thành công!",
"maximum-file-size": "Tối đa %1 kb",
"no-uploads-found": "Không có tải lên được tìm thấy",
"public-uploads-info": "Các file tải lên được xuất bản, mọi người đều có thể xem được.",
"private-uploads-info": "Các file tải lên được để ở chế độ bí mật, chỉ những người dùng đăng nhập mới có thể xem."
"public-uploads-info": "Tải lên là công khai, mọi người đều xem được.",
"private-uploads-info": "Tải lên là riêng tư, những ai đã đăng nhập mới có thể xem."
}

View File

@@ -91,7 +91,7 @@
"upload-a-picture": "Tải lên một hình ảnh",
"remove-uploaded-picture": "Xoá ảnh đã tải lên",
"upload-cover-picture": "Tải ảnh bìa lên",
"remove-cover-picture-confirm": "Bạn có thật sự muốn xóa nh ảnh này?",
"remove-cover-picture-confirm": "Bạn có chắc muốn xóa nh bìa này?",
"crop-picture": "Cắt ảnh",
"upload-cropped-picture": "Cắt và tải lên",
"avatar-background-colour": "Màu nền ảnh đại diện",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "房间 %1",
"chat.chatting-with": "与<span id=\"chat-with-name\"></span>聊天",
"chat.placeholder": "在此输入聊天消息,或者拖入图片,按下回车键以发送",
"chat.placeholder.mobile": "在此输入聊天信息",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "转到最近的信息",
"chat.usernames-and-x-others": "%1 和 %2 其他人",
"chat.chat-with-usernames": "与<span id=\"chat-with-name\"></span>聊天",

View File

@@ -1,8 +1,9 @@
{
"chat.room-id": "Room %1",
"chat.chatting-with": "與<span id=\"chat-with-name\"></span>聊天",
"chat.placeholder": "Type chat message here, drag & drop images, press enter to send",
"chat.placeholder.mobile": "Type chat message here",
"chat.placeholder": "Type chat message here, drag & drop images",
"chat.placeholder.mobile": "Type chat message",
"chat.placeholder.message-room": "Message #%1",
"chat.scroll-up-alert": "Go to most recent message",
"chat.usernames-and-x-others": "%1 & %2 others",
"chat.chat-with-usernames": "Chat with %1",

View File

@@ -166,6 +166,8 @@ paths:
$ref: 'write/topics/tid/read.yaml'
/topics/{tid}/bump:
$ref: 'write/topics/tid/bump.yaml'
/topics/{tid}/move:
$ref: 'write/topics/tid/move.yaml'
/tags/{tag}/follow:
$ref: 'write/tags/tag/follow.yaml'
/posts/{pid}:

View File

@@ -0,0 +1,29 @@
put:
tags:
- topics
summary: move topic to another category
description: |
This operation moved a topic from one category to another.
**Note**: This is a privileged call and can only be executed by administrators, global moderators, or the moderator for the category of the passed-in topic.
parameters:
- in: path
name: tid
schema:
type: string
required: true
description: a valid topic id
example: 1
responses:
'200':
description: Topic successfully moved
content:
application/json:
schema:
type: object
properties:
status:
$ref: ../../../components/schemas/Status.yaml#/Status
response:
type: object
properties: {}

View File

@@ -697,6 +697,12 @@ define('forum/chats', [
data.message.timestamp = Math.min(Date.now(), data.message.timestamp);
data.message.timestampISO = utils.toISOString(data.message.timestamp);
messages.appendChatMessage($('[component="chat/message/content"]'), data.message);
Chats.updateTeaser(data.roomId, {
content: utils.stripHTMLTags(utils.decodeHTMLEntities(data.message.content)),
user: data.message.fromUser,
timestampISO: data.message.timestampISO,
});
}
});
@@ -754,6 +760,31 @@ define('forum/chats', [
});
};
Chats.updateTeaser = async function (roomId, teaser) {
if (!ajaxify.data.template.chats || !app.user.userslug) {
return;
}
const roomEl = chatNavWrapper.find(`[data-roomid="${roomId}"]`);
if (roomEl.length) {
const html = await app.parseAndTranslate('partials/chats/room-teaser', {
teaser: teaser,
});
roomEl.find('[component="chat/room/teaser"]').html(html[0].outerHTML);
roomEl.find('.timeago').timeago();
} else {
const { rooms } = await api.get(`/chats`, { start: 0, perPage: 2 });
const room = rooms.find(r => parseInt(r.roomId, 10) === parseInt(roomId, 10));
if (room) {
const recentEl = components.get('chat/recent');
const html = await app.parseAndTranslate('chats', 'rooms', {
rooms: [room],
showBottomHr: true,
});
recentEl.prepend(html);
}
}
};
Chats.markChatPageElUnread = function (data) {
if (!ajaxify.data.template.chats) {
return;

View File

@@ -42,6 +42,7 @@ define('forum/header/chat', [
return;
}
chatPage.markChatPageElUnread(data);
chatPage.updateTeaser(data.roomId, data.teaser);
}
let { count } = await api.get('/chats/unread');

View File

@@ -97,14 +97,16 @@ define('forum/header/unread', ['hooks'], function (hooks) {
.toggleClass('hidden', count <= 0)
.text(count);
// persona mobile menu uses data-content
$('#mobile-menu [data-unread-url="' + url + '"]')
.attr('data-content', countText);
if (navLink.length) {
// persona mobile menu uses data-content
$('#mobile-menu [data-unread-url="' + url + '"]')
.attr('data-content', countText);
// harmony mobile unread badge, doesn't use data-content
$('[component="unread/count"][data-unread-url="' + url + '"]')
.toggleClass('hidden', count <= 0)
.text(countText);
// harmony mobile unread badge, doesn't use data-content
$('[component="unread/count"][data-unread-url="' + url + '"]')
.toggleClass('hidden', count <= 0)
.text(countText);
}
hooks.fire('action:unread.updateCount', { url, count });
}

View File

@@ -20,8 +20,9 @@ define('forum/infinitescroll', ['hooks', 'alerts', 'api'], function (hooks, aler
}
previousScrollTop = $(window).scrollTop();
$(window).off('scroll', startScrollTimeout).on('scroll', startScrollTimeout);
if ($body.height() <= $(window).height()) {
if ($body.height() <= $(window).height() && (
!ajaxify.data.hasOwnProperty('pageCount') || ajaxify.data.pageCount > 1
)) {
callback(1);
}
};

View File

@@ -1,10 +1,9 @@
'use strict';
define('chat', [
'components', 'taskbar', 'translator', 'hooks', 'bootbox', 'alerts', 'api',
], function (components, taskbar, translator, hooks, bootbox, alerts, api) {
'components', 'taskbar', 'translator', 'hooks', 'bootbox', 'alerts', 'api', 'scrollStop',
], function (components, taskbar, translator, hooks, bootbox, alerts, api, scrollStop) {
const module = {};
let newMessage = false;
module.openChat = function (roomId, uid) {
if (!app.user.uid) {
@@ -182,9 +181,11 @@ define('chat', [
return;
}
if (module.modalExists(data.roomId)) {
const modal = module.getModal(data.roomId);
const newMessage = parseInt(modal.attr('new-message'), 10) === 1;
data.self = parseInt(app.user.uid, 10) === parseInt(data.fromUid, 10) ? 1 : 0;
if (!newMessage) {
newMessage = data.self === 0;
modal.attr('new-message', data.self === 0 ? 1 : 0);
}
data.message.self = data.self;
data.message.timestamp = Math.min(Date.now(), data.message.timestamp);
@@ -290,11 +291,60 @@ define('chat', [
return $('#chat-modal-' + roomId).length !== 0;
};
module.initWidget = function (roomId, chatModal) {
require(['forum/chats', 'forum/chats/messages'], function (Chats, ChatsMessages) {
socket.emit('modules.chats.enter', roomId);
api.del(`/chats/${roomId}/state`, {});
chatModal.find('.timeago').timeago();
chatModal.find('[data-bs-toggle="tooltip"]').tooltip({
trigger: 'hover', container: '#content',
});
ChatsMessages.wrapImagesInLinks(chatModal.find('[component="chat/messages"] .chat-content'));
scrollStop.apply(chatModal.find('[component="chat/messages"] .chat-content'));
chatModal.on('mousemove keypress click', function () {
if (parseInt(chatModal.attr('new-message'), 10) === 1) {
api.del(`/chats/${roomId}/state`, {});
chatModal.removeAttr('new-message');
}
});
Chats.addActionHandlers(chatModal.find('[component="chat/message/window"]'), roomId);
Chats.addSendHandlers(roomId, chatModal.find('.chat-input'), chatModal.find('[data-action="send"]'));
Chats.createAutoComplete(roomId, chatModal.find('[component="chat/input"]'));
Chats.addScrollHandler(roomId, app.user.uid, chatModal.find('[component="chat/message/content"]'));
Chats.addScrollBottomHandler(roomId, chatModal.find('[component="chat/message/content"]'));
Chats.addParentHandler(chatModal.find('[component="chat/message/content"]'));
Chats.addCharactersLeftHandler(chatModal);
Chats.addTextareaResizeHandler(chatModal);
Chats.addTypingHandler(chatModal, roomId);
Chats.addIPHandler(chatModal);
Chats.addTooltipHandler(chatModal);
Chats.addUploadHandler({
dragDropAreaEl: chatModal.find('.modal-content'),
pasteEl: chatModal,
uploadFormEl: chatModal.find('[component="chat/upload"]'),
uploadBtnEl: chatModal.find('[component="chat/upload/button"]'),
inputEl: chatModal.find('[component="chat/input"]'),
});
ChatsMessages.addSocketListeners();
ChatsMessages.scrollToBottomAfterImageLoad(chatModal.find('.chat-content'));
hooks.fire('action:chat.loaded', chatModal);
});
};
module.createModal = function (data, callback) {
callback = callback || function () {};
require([
'scrollStop', 'forum/chats', 'forum/chats/messages', 'forum/chats/message-search',
], function (scrollStop, Chats, ChatsMessages, messageSearch) {
'forum/chats', 'forum/chats/messages', 'forum/chats/message-search',
], function (Chats, ChatsMessages, messageSearch) {
app.parseAndTranslate('chat', data, function (chatModal) {
const roomId = data.roomId;
if (module.modalExists(roomId)) {
@@ -305,45 +355,19 @@ define('chat', [
chatModal.attr('id', 'chat-modal-' + roomId);
chatModal.attr('data-roomid', roomId);
chatModal.attr('intervalId', 0);
chatModal.attr('data-uuid', uuid);
chatModal.css('position', 'fixed');
chatModal.appendTo($('body'));
chatModal.find('.timeago').timeago();
chatModal.find('[data-bs-toggle="tooltip"]').tooltip({ trigger: 'hover', container: '#content' });
ChatsMessages.wrapImagesInLinks(chatModal.find('[component="chat/messages"] .chat-content'));
module.center(chatModal);
app.loadJQueryUI(function () {
chatModal.find('.modal-content').resizable({
handles: 'n, e, s, w, se',
minHeight: 250,
minWidth: 400,
});
chatModal.find('.modal-content').on('resize', function (event, ui) {
if (ui.originalSize.height === ui.size.height) {
return;
}
chatModal.find('.modal-body').css('height', module.calculateChatListHeight(chatModal));
});
chatModal.draggable({
start: function () {
taskbar.updateActive(uuid);
chatModal.css({ bottom: 'auto', right: 'auto' });
},
stop: function () {
module.focusInput(chatModal);
},
distance: 10,
handle: '.modal-header',
});
});
scrollStop.apply(chatModal.find('[component="chat/messages"] .chat-content'));
module.center(chatModal);
makeModalResizeableDraggable(chatModal, uuid);
chatModal.find('#chat-close-btn').on('click', function () {
module.close(uuid);
});
@@ -380,9 +404,9 @@ define('chat', [
});
chatModal.on('mousemove keypress click', function () {
if (newMessage) {
if (parseInt(chatModal.attr('new-message'), 10) === 1) {
api.del(`/chats/${roomId}/state`, {});
newMessage = false;
chatModal.removeAttr('new-message');
}
});
@@ -433,6 +457,36 @@ define('chat', [
});
};
function makeModalResizeableDraggable(chatModal, uuid) {
app.loadJQueryUI(function () {
chatModal.find('.modal-content').resizable({
handles: 'n, e, s, w, se',
minHeight: 250,
minWidth: 400,
});
chatModal.find('.modal-content').on('resize', function (event, ui) {
if (ui.originalSize.height === ui.size.height) {
return;
}
chatModal.find('.modal-body').css('height', module.calculateChatListHeight(chatModal));
});
chatModal.draggable({
start: function () {
taskbar.updateActive(uuid);
chatModal.css({ bottom: 'auto', right: 'auto' });
},
stop: function () {
module.focusInput(chatModal);
},
distance: 10,
handle: '.modal-header',
});
});
}
module.focusInput = function (chatModal) {
setTimeout(function () {
chatModal.find('[component="chat/input"]').focus();
@@ -441,8 +495,6 @@ define('chat', [
module.close = function (uuid) {
const chatModal = $('.chat-modal[data-uuid="' + uuid + '"]');
clearInterval(chatModal.attr('intervalId'));
chatModal.attr('intervalId', 0);
chatModal.remove();
chatModal.data('modal', null);
taskbar.discard('chat', uuid);
@@ -529,8 +581,6 @@ define('chat', [
const chatModal = $('.chat-modal[data-uuid="' + uuid + '"]');
chatModal.addClass('hide');
taskbar.minimize('chat', uuid);
clearInterval(chatModal.attr('intervalId'));
chatModal.attr('intervalId', 0);
hooks.fire('action:chat.minimized', {
uuid: uuid,
modal: chatModal,

View File

@@ -37,7 +37,7 @@ async function rateLimitExceeded(caller, field) {
}
chatsAPI.list = async (caller, { uid = caller.uid, start, stop, page, perPage } = {}) => {
if (!start && !stop && !page) {
if ((!utils.isNumber(start) || !utils.isNumber(stop)) && !utils.isNumber(page)) {
throw new Error('[[error:invalid-data]]');
}

View File

@@ -4,9 +4,12 @@ const validator = require('validator');
const user = require('../user');
const topics = require('../topics');
const categories = require('../categories');
const posts = require('../posts');
const meta = require('../meta');
const privileges = require('../privileges');
const events = require('../events');
const batch = require('../batch');
const activitypubApi = require('./activitypub');
const apiHelpers = require('./helpers');
@@ -306,3 +309,48 @@ topicsAPI.bump = async (caller, { tid }) => {
await topics.markAsUnreadForAll(tid);
topics.pushUnreadCount(caller.uid);
};
topicsAPI.move = async (caller, { tid, cid }) => {
const canMove = await privileges.categories.isAdminOrMod(cid, caller.uid);
if (!canMove) {
throw new Error('[[error:no-privileges]]');
}
const tids = Array.isArray(tid) ? tid : [tid];
const uids = await user.getUidsFromSet('users:online', 0, -1);
const cids = [parseInt(cid, 10)];
await batch.processArray(tids, async (tids) => {
await Promise.all(tids.map(async (tid) => {
const canMove = await privileges.topics.isAdminOrMod(tid, caller.uid);
if (!canMove) {
throw new Error('[[error:no-privileges]]');
}
const topicData = await topics.getTopicFields(tid, ['tid', 'cid', 'slug', 'deleted']);
if (!cids.includes(topicData.cid)) {
cids.push(topicData.cid);
}
await topics.tools.move(tid, {
cid,
uid: caller.uid,
});
const notifyUids = await privileges.categories.filterUids('topics:read', topicData.cid, uids);
socketHelpers.emitToUids('event:topic_moved', topicData, notifyUids);
if (!topicData.deleted) {
socketHelpers.sendNotificationToTopicOwner(tid, caller.uid, 'move', 'notifications:moved-your-topic');
}
await events.log({
type: `topic-move`,
uid: caller.uid,
ip: caller.ip,
tid: tid,
fromCid: topicData.cid,
toCid: cid,
});
}));
}, { batch: 10 });
await categories.onTopicsMoved(cids);
};

View File

@@ -207,3 +207,10 @@ Topics.bump = async (req, res) => {
helpers.formatApiResponse(200, res);
};
Topics.move = async (req, res) => {
const { cid } = req.body;
await api.topics.move(req, { cid, ...req.params });
helpers.formatApiResponse(200, res);
};

View File

@@ -75,6 +75,7 @@ events.types = [
'export:uploads',
'account-locked',
'getUsersCSV',
'getGroupCSV',
'chat-room-deleted',
// To add new types from plugins, just Array.push() to this array
];

View File

@@ -1,6 +1,7 @@
'use strict';
const winston = require('winston');
const validator = require('validator');
const batch = require('../batch');
const db = require('../database');
@@ -8,6 +9,7 @@ const notifications = require('../notifications');
const user = require('../user');
const io = require('../socket.io');
const plugins = require('../plugins');
const utils = require('../utils');
module.exports = function (Messaging) {
Messaging.setUserNotificationSetting = async (uid, roomId, value) => {
@@ -66,6 +68,13 @@ module.exports = function (Messaging) {
// push unread count only for private rooms
if (!isPublic) {
const uids = await Messaging.getAllUidsInRoomFromSet(`chat:room:${roomId}:uids:online`);
unreadData.teaser = {
content: validator.escape(
String(utils.stripHTMLTags(utils.decodeHTMLEntities(messageObj.content)))
),
user: messageObj.fromUser,
timestampISO: messageObj.timestampISO,
};
Messaging.pushUnreadCount(uids, unreadData);
}

View File

@@ -155,6 +155,7 @@ Plugins.get = async function (id) {
const url = `${nconf.get('registry') || 'https://packages.nodebb.org'}/api/v1/plugins/${id}`;
const { response, body } = await request.get(url);
if (!response.ok) {
console.log(response);
throw new Error(`[[error:unable-to-load-plugin, ${id}]]`);
}
let normalised = await Plugins.normalise([body ? body.payload : {}]);
@@ -171,6 +172,7 @@ Plugins.list = async function (matching) {
try {
const { response, body } = await request.get(url);
if (!response.ok) {
console.log(response);
throw new Error(`[[error:unable-to-load-plugins-from-nbbpm]]`);
}
return await Plugins.normalise(body);
@@ -184,6 +186,7 @@ Plugins.listTrending = async () => {
const url = `${nconf.get('registry') || 'https://packages.nodebb.org'}/api/v1/analytics/top/week`;
const { response, body } = await request.get(url);
if (!response.ok) {
console.log(response);
throw new Error(`[[error:unable-to-load-trending-plugins]]`);
}
return body;

View File

@@ -22,7 +22,7 @@ let sanitizeConfig = {
...sanitize.defaults.allowedAttributes,
a: ['href', 'name', 'hreflang', 'media', 'rel', 'target', 'type'],
img: ['alt', 'height', 'ismap', 'src', 'usemap', 'width', 'srcset'],
iframe: ['height', 'name', 'src', 'width'],
iframe: ['height', 'name', 'src', 'width', 'allow', 'frameborder'],
video: ['autoplay', 'playsinline', 'controls', 'height', 'loop', 'muted', 'poster', 'preload', 'src', 'width'],
audio: ['autoplay', 'controls', 'loop', 'muted', 'preload', 'src'],
source: ['type', 'src', 'srcset', 'sizes', 'media', 'height', 'width'],

View File

@@ -49,5 +49,7 @@ module.exports = function () {
setupApiRoute(router, 'delete', '/:tid/read', [...middlewares, middleware.assert.topic], controllers.write.topics.markUnread);
setupApiRoute(router, 'put', '/:tid/bump', [...middlewares, middleware.assert.topic], controllers.write.topics.bump);
setupApiRoute(router, 'put', '/:tid/move', [...middlewares, middleware.assert.topic], controllers.write.topics.move);
return router;
};

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