mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-02-28 09:31:17 +01:00
Merge branch 'master' into develop
This commit is contained in:
78
CHANGELOG.md
78
CHANGELOG.md
@@ -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
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "nodebb",
|
||||
"license": "GPL-3.0",
|
||||
"description": "NodeBB Forum",
|
||||
"version": "3.8.3",
|
||||
"version": "3.8.4",
|
||||
"homepage": "https://www.nodebb.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -104,7 +104,7 @@
|
||||
"nodebb-plugin-ntfy": "1.7.5",
|
||||
"nodebb-plugin-spam-be-gone": "2.2.2",
|
||||
"nodebb-rewards-essentials": "1.0.0",
|
||||
"nodebb-theme-harmony": "1.2.63",
|
||||
"nodebb-theme-harmony": "1.2.64",
|
||||
"nodebb-theme-lavender": "7.1.8",
|
||||
"nodebb-theme-peace": "2.2.6",
|
||||
"nodebb-theme-persona": "13.3.25",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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]]');
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ const os = require('os');
|
||||
const user = require('../user');
|
||||
const meta = require('../meta');
|
||||
const topics = require('../topics');
|
||||
const privileges = require('../privileges');
|
||||
|
||||
const SocketMeta = module.exports;
|
||||
SocketMeta.rooms = {};
|
||||
@@ -44,6 +45,20 @@ SocketMeta.rooms.enter = async function (socket, data) {
|
||||
throw new Error('[[error:not-allowed]]');
|
||||
}
|
||||
|
||||
if (data.enter && data.enter.startsWith('topic_')) {
|
||||
const tid = data.enter.split('_').pop();
|
||||
if (!await privileges.topics.can('topics:read', tid, socket.uid)) {
|
||||
throw new Error('[[error:no-privileges]]');
|
||||
}
|
||||
}
|
||||
|
||||
if (data.enter && data.enter.startsWith('category_')) {
|
||||
const cid = data.enter.split('_').pop();
|
||||
if (!await privileges.categories.can('read', cid, socket.uid)) {
|
||||
throw new Error('[[error:no-privileges]]');
|
||||
}
|
||||
}
|
||||
|
||||
leaveCurrentRoom(socket);
|
||||
|
||||
if (data.enter) {
|
||||
|
||||
@@ -64,7 +64,7 @@ module.exports = function (User) {
|
||||
'w'
|
||||
);
|
||||
fs.promises.appendFile(fd, `${fields.map(f => `"${f}"`).join(',')}\n`);
|
||||
await batch.processSortedSet('group:administrators:members', async (uids) => {
|
||||
await batch.processSortedSet('users:joindate', async (uids) => {
|
||||
const userFieldsToLoad = fields.filter(field => field !== 'ip' && field !== 'password');
|
||||
const usersData = await User.getUsersFields(uids, userFieldsToLoad);
|
||||
let userIps = [];
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<div class="d-flex flex-column mt-3 ms-3">
|
||||
{{{ each hooks.methods }}}
|
||||
<div class="mb-3">
|
||||
<strong>{hooks.methods.id}</strong>
|
||||
<span>{hooks.methods.id}</span>
|
||||
<span class="text-secondary text-sm">Priority: {hooks.methods.priority}</span>
|
||||
|
||||
<button class="btn btn-light btn-sm float-end" type="button" data-bs-toggle="collapse" data-bs-target="#{hooks.methods.index}" aria-expanded="false" aria-controls="{hooks.methods.index}">
|
||||
|
||||
@@ -31,15 +31,7 @@
|
||||
{{{ end }}}
|
||||
{{{ end }}}
|
||||
</div>
|
||||
|
||||
{{{ if ./teaser }}}
|
||||
<div class="teaser-content text-sm line-clamp-3 text-break">
|
||||
{buildAvatar(./teaser.user, "14px", true, "align-middle")}
|
||||
<strong class="text-xs fw-semibold teaser-username">{./teaser.user.username}:</strong>
|
||||
{./teaser.content}
|
||||
</div>
|
||||
<div class="teaser-timestamp text-muted text-xs">{{{ if ./teaser.timeagoLong }}}{./teaser.timeagoLong}{{{ else }}}<span class="timeago" title="{./teaser.timestampISO}"></span>{{{ end }}}</div>
|
||||
{{{ end }}}
|
||||
<!-- IMPORT partials/chats/room-teaser.tpl -->
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@@ -52,4 +44,8 @@
|
||||
</div>
|
||||
{{{ if !@last }}}
|
||||
<hr class="my-1" />
|
||||
{{{ else }}}
|
||||
{{{ if showBottomHr }}}
|
||||
<hr class="my-1" />
|
||||
{{{ end }}}
|
||||
{{{ end }}}
|
||||
|
||||
10
src/views/partials/chats/room-teaser.tpl
Normal file
10
src/views/partials/chats/room-teaser.tpl
Normal file
@@ -0,0 +1,10 @@
|
||||
<div component="chat/room/teaser">
|
||||
{{{ if ./teaser }}}
|
||||
<div class="teaser-content text-sm line-clamp-3 text-break">
|
||||
{buildAvatar(./teaser.user, "14px", true, "align-middle")}
|
||||
<strong class="text-xs fw-semibold teaser-username">{./teaser.user.username}:</strong>
|
||||
{./teaser.content}
|
||||
</div>
|
||||
<div class="teaser-timestamp text-muted text-xs">{{{ if ./teaser.timeagoLong }}}{./teaser.timeagoLong}{{{ else }}}<span class="timeago" title="{./teaser.timestampISO}"></span>{{{ end }}}</div>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
@@ -15,6 +15,7 @@ const db = require('./mocks/databasemock');
|
||||
const user = require('../src/user');
|
||||
const groups = require('../src/groups');
|
||||
const categories = require('../src/categories');
|
||||
const topics = require('../src/topics');
|
||||
const helpers = require('./helpers');
|
||||
const meta = require('../src/meta');
|
||||
const events = require('../src/events');
|
||||
@@ -45,6 +46,12 @@ describe('socket.io', () => {
|
||||
await user.email.confirmByUid(regularUid);
|
||||
|
||||
cid = data[2].cid;
|
||||
await topics.post({
|
||||
uid: adminUid,
|
||||
cid: cid,
|
||||
title: 'Test Topic',
|
||||
content: 'Test topic content',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user