mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-07-04 14:07:35 +02:00
Merge commit 'a73f269fcee87118aff655ea4503e440be7b8956' into v3.x
This commit is contained in:
138
CHANGELOG.md
138
CHANGELOG.md
@@ -1,3 +1,141 @@
|
||||
#### v3.8.3 (2024-06-27)
|
||||
|
||||
##### Chores
|
||||
|
||||
* up themes (b15a5894)
|
||||
* up harmony (3eb69c58)
|
||||
* up harmony (b98333f3)
|
||||
* up dbsearch (8a42db6f)
|
||||
* use nodebb fork of spider-detector (3a1b39c9)
|
||||
* up 2factor (142de2ca)
|
||||
* incrementing version number - v3.8.2 (72d91251)
|
||||
* update changelog for v3.8.2 (3854a434)
|
||||
* 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
|
||||
|
||||
* closes #12656, only send required meta/link tags on /api calls (64875b3f)
|
||||
* show links in post queue (500e3342)
|
||||
* show connetion count on /info (60b4bc66)
|
||||
* make upload scores descending for ordering (3ec44d64)
|
||||
* add isACP to config, closes #12623 (c51b772f)
|
||||
* allow passing min,max to sortedSetsCardSum (70b4a0e2)
|
||||
* add voters/upvoters v3 routes (1aaa6cbb)
|
||||
|
||||
##### Bug Fixes
|
||||
|
||||
* wront topic events showing up in topic (54b01395)
|
||||
* dont show self in suggested topics (381bbb04)
|
||||
* #12645, use titleRaw like reply button (3332480c)
|
||||
* update follower/following counts after removing uid from zsets (6f6cfb1a)
|
||||
* suggested topic tid (351ee71d)
|
||||
* #12633, don't check post index (6e3b012b)
|
||||
* recent chat pagination, closes #12637 (f7c9b7ae)
|
||||
* info.tpl table (6f79d305)
|
||||
* closes #12632, dont load data twice (66adfa29)
|
||||
* don't error if file required too early (4430de8c)
|
||||
* require of spider-detector (be86d8ef)
|
||||
* return early for guests/spiders (8d56e097)
|
||||
* dont show error alert when user user mouse overs votes (6bbe3d1c)
|
||||
* dont load chat rooms for quests/spiders (ca4a7751)
|
||||
* set uid in case its spider(-1), closes #12621 (9d74539a)
|
||||
* dont add spiders to online_guests room (bcd4997d)
|
||||
* dont autoconnect for spiders, closes #12620 (b6671d16)
|
||||
* #12614 fix html markup for widget containers (56b5850a)
|
||||
|
||||
##### Other Changes
|
||||
|
||||
* remove unused winston (69ce3bf0)
|
||||
* remove unused (adb0566f)
|
||||
* fix semicolons (795a0daa)
|
||||
* fix whitespace (b4db2f7f)
|
||||
|
||||
##### Performance Improvements
|
||||
|
||||
* cleanup sessions every 30 seconds (26feb2bb)
|
||||
* change revokeSession to work with an array of sids (172bc249)
|
||||
* dont make db call if posts is already loaded client side (461e95d8)
|
||||
* if sigs disabled dont filter uids (73241bd5)
|
||||
* cache isAdmin, isGlobalMod checks (fedfce7b)
|
||||
* get rid of async call in user load for expiring bans (023d52a3)
|
||||
* call getIconbackgrounds once (1dadd16f)
|
||||
* get rid of more calls, fix other profile pages #12632 (5c6a853e)
|
||||
|
||||
##### Refactors
|
||||
|
||||
* sessionUUID (#12658) (d6c946cf)
|
||||
* move delete call (65a91ea5)
|
||||
* use array.some (85b329af)
|
||||
* add placeholders on demand (8f486b1b)
|
||||
* move getTopicData call to avoid db calls when its not in cache (252d0df7)
|
||||
* remove exits check (74dd2844)
|
||||
* move als requires, move autoLocale to api/page routes (3356022a)
|
||||
* move requires down (8eccdb48)
|
||||
* posts cache to get rid of require in functions (236ac323)
|
||||
* closes #12629, allow passing arrays to meta.userOrGroupExists (bad15643)
|
||||
* suggest topics, use strings for tids (8ded36f2)
|
||||
* #12623, add filter:config.get.admin (2d86552b)
|
||||
* add sanity checks to sio (e98f1848)
|
||||
|
||||
##### Tests
|
||||
|
||||
* dont track session for api/v3 (#12660) (61e5293a)
|
||||
* move set (9108c900)
|
||||
* spec (41f1cd69)
|
||||
* spec (b148d0fc)
|
||||
* fix path replace (9ecee782)
|
||||
* update openapi spec (9af3a2da)
|
||||
* fix tests (c2f63090)
|
||||
* return empty array on db.exists([]); (1b283ccc)
|
||||
* fix test only set for spiders (7c2a3a6e)
|
||||
* fix post test (42230300)
|
||||
|
||||
#### v3.8.2 (2024-05-29)
|
||||
|
||||
##### Chores
|
||||
|
||||
@@ -137,7 +137,8 @@
|
||||
"sitemapTopics": 500,
|
||||
"maintenanceMode": 0,
|
||||
"maintenanceModeStatus": 503,
|
||||
"voteVisibility": "privileged",
|
||||
"upvoteVisibility": "all",
|
||||
"downvoteVisibility": "privileged",
|
||||
"maximumInvites": 0,
|
||||
"username:disableEdit": 0,
|
||||
"email:disableEdit": 0,
|
||||
|
||||
@@ -107,8 +107,8 @@
|
||||
"nodebb-theme-harmony": "1.2.63",
|
||||
"nodebb-theme-lavender": "7.1.8",
|
||||
"nodebb-theme-peace": "2.2.6",
|
||||
"nodebb-theme-persona": "13.3.24",
|
||||
"nodebb-widget-essentials": "7.0.16",
|
||||
"nodebb-theme-persona": "13.3.25",
|
||||
"nodebb-widget-essentials": "7.0.18",
|
||||
"nodemailer": "6.9.13",
|
||||
"nprogress": "0.2.0",
|
||||
"passport": "0.7.0",
|
||||
|
||||
@@ -2,10 +2,14 @@
|
||||
"reputation": "Reputation Settings",
|
||||
"disable": "Disable Reputation System",
|
||||
"disable-down-voting": "Disable Down Voting",
|
||||
"vote-visibility": "Vote visibility",
|
||||
"vote-visibility-all": "Everyone can see votes",
|
||||
"vote-visibility-loggedin": "Only logged in users can see votes",
|
||||
"vote-visibility-privileged": "Only privileged users like admins & moderators can see votes",
|
||||
"upvote-visibility": "Up Vote visibility",
|
||||
"upvote-visibility-all": "Everyone can see up votes",
|
||||
"upvote-visibility-loggedin": "Only logged in users can see up votes",
|
||||
"upvote-visibility-privileged": "Only privileged users like admins & moderators can see up votes",
|
||||
"downvote-visibility": "Down Vote visibility",
|
||||
"downvote-visibility-all": "Everyone can see down votes",
|
||||
"downvote-visibility-loggedin": "Only logged in users can see down votes",
|
||||
"downvote-visibility-privileged": "Only privileged users like admins & moderators can see down votes",
|
||||
"thresholds": "Activity Thresholds",
|
||||
"min-rep-upvote": "Minimum reputation to upvote posts",
|
||||
"upvotes-per-day": "Upvotes per day (set to 0 for unlimited upvotes)",
|
||||
|
||||
@@ -382,7 +382,9 @@ get:
|
||||
type: number
|
||||
downvote:disabled:
|
||||
type: number
|
||||
voteVisibility:
|
||||
upvoteVisibility:
|
||||
type: string
|
||||
downvoteVisibility:
|
||||
type: string
|
||||
feeds:disableRSS:
|
||||
type: number
|
||||
|
||||
@@ -28,6 +28,8 @@ get:
|
||||
type: number
|
||||
downvoteCount:
|
||||
type: number
|
||||
showUpvotes:
|
||||
type: boolean
|
||||
showDownvotes:
|
||||
type: boolean
|
||||
upvoters:
|
||||
|
||||
@@ -684,6 +684,31 @@ define('forum/chats', [
|
||||
};
|
||||
|
||||
Chats.addSocketListeners = function () {
|
||||
socket.on('event:new_notification', async function (notif) {
|
||||
const { type, roomId } = notif;
|
||||
if (ajaxify.data.template.chats && app.user.userslug && (type === 'new-chat' || type === 'new-group-chat')) {
|
||||
const inRoom = parseInt(roomId, 10) === parseInt(ajaxify.data.roomId, 10);
|
||||
if (inRoom) {
|
||||
return;
|
||||
}
|
||||
const { rooms } = await api.get(`/chats`, { start: 0, perPage: 1 });
|
||||
const room = rooms.find(r => parseInt(r.roomId, 10) === parseInt(roomId, 10));
|
||||
if (room) {
|
||||
const roomEl = chatNavWrapper.find(`[data-roomid="${roomId}"]`);
|
||||
if (roomEl.length) {
|
||||
updateTeaser(roomId, room.teaser);
|
||||
} else {
|
||||
const recentEl = components.get('chat/recent');
|
||||
const html = await app.parseAndTranslate('chats', 'rooms', {
|
||||
rooms: [room],
|
||||
showBottomHr: true,
|
||||
});
|
||||
recentEl.prepend(html);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('event:chats.receive', function (data) {
|
||||
if (chatModule.isFromBlockedUser(data.fromUid)) {
|
||||
return;
|
||||
@@ -697,9 +722,26 @@ 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);
|
||||
|
||||
updateTeaser(data.roomId, {
|
||||
content: utils.stripHTMLTags(utils.decodeHTMLEntities(data.message.content)),
|
||||
user: data.message.fromUser,
|
||||
timestampISO: data.message.timestampISO,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
async function updateTeaser(roomId, teaser) {
|
||||
const roomEl = $(`[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();
|
||||
}
|
||||
}
|
||||
|
||||
socket.on('event:chats.public.unread', function (data) {
|
||||
if (
|
||||
chatModule.isFromBlockedUser(data.fromUid) ||
|
||||
|
||||
@@ -297,7 +297,7 @@ define('forum/topic', [
|
||||
destroyed = true;
|
||||
}
|
||||
$(window).one('action:ajaxify.start', destroyTooltip);
|
||||
$('[component="topic"]').on('mouseenter', '[component="post/parent"] a, [component="post/content"] a, [component="topic/event"] a', async function () {
|
||||
$('[component="topic"]').on('mouseenter', '[component="post/parent"], [component="post/content"] a, [component="topic/event"] a', async function () {
|
||||
const link = $(this);
|
||||
destroyed = false;
|
||||
|
||||
|
||||
@@ -9,17 +9,24 @@ define('forum/topic/votes', [
|
||||
|
||||
Votes.addVoteHandler = function () {
|
||||
_showTooltip = {};
|
||||
if (canSeeVotes()) {
|
||||
if (canSeeUpVotes()) {
|
||||
components.get('topic').on('mouseenter', '[data-pid] [component="post/vote-count"]', loadDataAndCreateTooltip);
|
||||
components.get('topic').on('mouseleave', '[data-pid] [component="post/vote-count"]', destroyTooltip);
|
||||
}
|
||||
};
|
||||
|
||||
function canSeeVotes() {
|
||||
const { voteVisibility, privileges } = ajaxify.data;
|
||||
function canSeeUpVotes() {
|
||||
const { upvoteVisibility, privileges } = ajaxify.data;
|
||||
return privileges.isAdminOrMod ||
|
||||
voteVisibility === 'all' ||
|
||||
(voteVisibility === 'loggedin' && config.loggedIn);
|
||||
upvoteVisibility === 'all' ||
|
||||
(upvoteVisibility === 'loggedin' && config.loggedIn);
|
||||
}
|
||||
|
||||
function canSeeVotes() {
|
||||
const { upvoteVisibility, downvoteVisibility, privileges } = ajaxify.data;
|
||||
return privileges.isAdminOrMod ||
|
||||
upvoteVisibility === 'all' || downvoteVisibility === 'all' ||
|
||||
((upvoteVisibility === 'loggedin' || downvoteVisibility === 'loggedin') && config.loggedIn);
|
||||
}
|
||||
|
||||
function destroyTooltip() {
|
||||
|
||||
@@ -61,11 +61,12 @@ define('categoryFilter', ['categorySearch', 'api', 'hooks'], function (categoryS
|
||||
}
|
||||
});
|
||||
|
||||
el.on('click', '[component="category/list"] [data-cid]', function () {
|
||||
el.on('click', '[component="category/list"] [data-cid]', function (ev) {
|
||||
const listEl = el.find('[component="category/list"]');
|
||||
const categoryEl = $(this);
|
||||
const link = categoryEl.find('a').attr('href');
|
||||
if (link && link !== '#' && link.length) {
|
||||
ev.stopPropagation();
|
||||
return;
|
||||
}
|
||||
const cid = categoryEl.attr('data-cid');
|
||||
|
||||
@@ -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]]');
|
||||
}
|
||||
|
||||
|
||||
@@ -314,12 +314,19 @@ postsAPI.getVoters = async function (caller, data) {
|
||||
}
|
||||
const { pid } = data;
|
||||
const cid = await posts.getCidByPid(pid);
|
||||
if (!await canSeeVotes(caller.uid, cid)) {
|
||||
const [canSeeUpvotes, canSeeDownvotes] = await Promise.all([
|
||||
canSeeVotes(caller.uid, cid, 'upvoteVisibility'),
|
||||
canSeeVotes(caller.uid, cid, 'downvoteVisibility'),
|
||||
]);
|
||||
|
||||
if (!canSeeUpvotes && !canSeeDownvotes) {
|
||||
throw new Error('[[error:no-privileges]]');
|
||||
}
|
||||
const showDownvotes = !meta.config['downvote:disabled'];
|
||||
const repSystemDisabled = meta.config['reputation:disabled'];
|
||||
const showUpvotes = canSeeUpvotes && !repSystemDisabled;
|
||||
const showDownvotes = canSeeDownvotes && !meta.config['downvote:disabled'] && !repSystemDisabled;
|
||||
const [upvoteUids, downvoteUids] = await Promise.all([
|
||||
db.getSetMembers(`pid:${data.pid}:upvote`),
|
||||
showUpvotes ? db.getSetMembers(`pid:${data.pid}:upvote`) : [],
|
||||
showDownvotes ? db.getSetMembers(`pid:${data.pid}:downvote`) : [],
|
||||
]);
|
||||
|
||||
@@ -331,6 +338,7 @@ postsAPI.getVoters = async function (caller, data) {
|
||||
return {
|
||||
upvoteCount: upvoters.length,
|
||||
downvoteCount: downvoters.length,
|
||||
showUpvotes: showUpvotes,
|
||||
showDownvotes: showDownvotes,
|
||||
upvoters: upvoters,
|
||||
downvoters: downvoters,
|
||||
@@ -343,7 +351,7 @@ postsAPI.getUpvoters = async function (caller, data) {
|
||||
}
|
||||
const { pid } = data;
|
||||
const cid = await posts.getCidByPid(pid);
|
||||
if (!await canSeeVotes(caller.uid, cid)) {
|
||||
if (!await canSeeVotes(caller.uid, cid, 'upvoteVisibility')) {
|
||||
throw new Error('[[error:no-privileges]]');
|
||||
}
|
||||
|
||||
@@ -370,7 +378,7 @@ postsAPI.getUpvoters = async function (caller, data) {
|
||||
};
|
||||
};
|
||||
|
||||
async function canSeeVotes(uid, cids) {
|
||||
async function canSeeVotes(uid, cids, type) {
|
||||
const isArray = Array.isArray(cids);
|
||||
if (!isArray) {
|
||||
cids = [cids];
|
||||
@@ -389,8 +397,8 @@ async function canSeeVotes(uid, cids) {
|
||||
(
|
||||
cidToAllowed[cid] &&
|
||||
(
|
||||
meta.config.voteVisibility === 'all' ||
|
||||
(meta.config.voteVisibility === 'loggedin' && parseInt(uid, 10) > 0)
|
||||
meta.config[type] === 'all' ||
|
||||
(meta.config[type] === 'loggedin' && parseInt(uid, 10) > 0)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -308,12 +308,14 @@ Controllers.manifest = async function (req, res) {
|
||||
if (meta.config['brand:maskableIcon']) {
|
||||
manifest.icons.push({
|
||||
src: `${nconf.get('relative_path')}/assets/uploads/system/maskableicon-orig.png`,
|
||||
sizes: '512x512',
|
||||
type: 'image/png',
|
||||
purpose: 'maskable',
|
||||
});
|
||||
} else if (meta.config['brand:touchIcon']) {
|
||||
manifest.icons.push({
|
||||
src: `${nconf.get('relative_path')}/assets/uploads/system/touchicon-orig.png`,
|
||||
sizes: '512x512',
|
||||
type: 'image/png',
|
||||
purpose: 'maskable',
|
||||
});
|
||||
|
||||
@@ -97,7 +97,8 @@ topicsController.get = async function getTopic(req, res, next) {
|
||||
topicData.topicStaleDays = meta.config.topicStaleDays;
|
||||
topicData['reputation:disabled'] = meta.config['reputation:disabled'];
|
||||
topicData['downvote:disabled'] = meta.config['downvote:disabled'];
|
||||
topicData.voteVisibility = meta.config.voteVisibility;
|
||||
topicData.upvoteVisibility = meta.config.upvoteVisibility;
|
||||
topicData.downvoteVisibility = meta.config.downvoteVisibility;
|
||||
topicData['feeds:disableRSS'] = meta.config['feeds:disableRSS'] || 0;
|
||||
topicData['signatures:hideDuplicates'] = meta.config['signatures:hideDuplicates'];
|
||||
topicData.bookmarkThreshold = meta.config.bookmarkThreshold;
|
||||
|
||||
@@ -15,7 +15,7 @@ function setupWinston() {
|
||||
}
|
||||
|
||||
const formats = [];
|
||||
if (nconf.get('log-colorize') !== 'false') {
|
||||
if (nconf.get('log-colorize') !== 'false' && nconf.get('log-colorize') !== false) {
|
||||
formats.push(winston.format.colorize());
|
||||
}
|
||||
|
||||
|
||||
20
src/upgrades/3.8.4/downvote-visibility-config.js
Normal file
20
src/upgrades/3.8.4/downvote-visibility-config.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/* eslint-disable no-await-in-loop */
|
||||
|
||||
'use strict';
|
||||
|
||||
const db = require('../../database');
|
||||
|
||||
module.exports = {
|
||||
name: 'Add downvote visibility config field',
|
||||
timestamp: Date.UTC(2024, 6, 17),
|
||||
method: async function () {
|
||||
const current = await db.getObjectField('config', 'voteVisibility');
|
||||
if (current) {
|
||||
await db.setObject('config', {
|
||||
upvoteVisibility: current,
|
||||
downvoteVisibility: current,
|
||||
});
|
||||
await db.deleteObjectField('config', 'voteVisibility');
|
||||
}
|
||||
},
|
||||
};
|
||||
@@ -1,28 +1,28 @@
|
||||
<div class="hooks-list panel-group px-lg-4" id="accordion" role="tablist" aria-multiselectable="true">
|
||||
<div class="hooks-list px-lg-4" id="accordion" role="tablist" aria-multiselectable="true">
|
||||
{{{ each hooks }}}
|
||||
<div class="card">
|
||||
<div class="card-header" role="tab">
|
||||
<h6 class="mb-0">
|
||||
<a style="text-transform: none;" class="text-reset text-decoration-none" role="button" data-bs-toggle="collapse" data-bs-parent="#accordion" data-bs-target="#{hooks.index}" aria-expanded="true" aria-controls="{hooks.index}">{hooks.hookName}</a>
|
||||
<span class="float-end">{hooks.count} hooks</span>
|
||||
<div class="mb-3 border rounded p-2">
|
||||
<div class="" role="tab">
|
||||
<h6 class="mb-0 ps-2 d-flex justify-content-between align-items-center">
|
||||
<span>{hooks.hookName}</span>
|
||||
<button class="btn-ghost-sm" data-bs-toggle="collapse" data-bs-parent="#accordion" data-bs-target="#{hooks.index}" aria-expanded="true" aria-controls="{hooks.index}">View hooks ({hooks.count})</button>
|
||||
</h6>
|
||||
</div>
|
||||
<div id="{hooks.index}" class="accordion-collapse collapse" role="tabpanel">
|
||||
<div class="card-body">
|
||||
{{{ each hooks.methods }}}
|
||||
<div class="mb-3">
|
||||
<strong>{hooks.methods.id}</strong>
|
||||
Priority: {hooks.methods.priority}
|
||||
<div class="d-flex flex-column mt-3 ms-3">
|
||||
{{{ each hooks.methods }}}
|
||||
<div class="mb-3">
|
||||
<span>{hooks.methods.id}</span>
|
||||
<span class="text-secondary text-sm">Priority: {hooks.methods.priority}</span>
|
||||
|
||||
<button class="btn btn-primary btn-sm float-end" type="button" data-bs-toggle="collapse" data-bs-target="#{hooks.methods.index}" aria-expanded="false" aria-controls="{hooks.methods.index}">
|
||||
Show Code <i class="fa fa-eye"></i>
|
||||
</button>
|
||||
<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}">
|
||||
<i class="fa fa-eye"></i> Show Code
|
||||
</button>
|
||||
</div>
|
||||
<div class="collapse" id="{hooks.methods.index}">
|
||||
<pre class="p-3 text-bg-light border rounded">{hooks.methods.method}</pre>
|
||||
</div>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
<div class="collapse" id="{hooks.methods.index}">
|
||||
<pre class="p-3 text-bg-light border border-secondary rounded">{hooks.methods.method}</pre>
|
||||
</div>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{{ end }}}
|
||||
|
||||
@@ -14,12 +14,20 @@
|
||||
<input type="checkbox" class="form-check-input" id="downvote:disabled" data-field="downvote:disabled">
|
||||
<label for="downvote:disabled" class="form-check-label">[[admin/settings/reputation:disable-down-voting]]</label>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="upvoteVisibility" class="form-check-label">[[admin/settings/reputation:upvote-visibility]]</label>
|
||||
<select id="upvoteVisibility" data-field="upvoteVisibility" class="form-select">
|
||||
<option value="all">[[admin/settings/reputation:upvote-visibility-all]]</option>
|
||||
<option value="loggedin">[[admin/settings/reputation:upvote-visibility-loggedin]]</option>
|
||||
<option value="privileged">[[admin/settings/reputation:upvote-visibility-privileged]]</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="voteVisibility" class="form-check-label">[[admin/settings/reputation:vote-visibility]]</label>
|
||||
<select id="voteVisibility" data-field="voteVisibility" class="form-select">
|
||||
<option value="all">[[admin/settings/reputation:vote-visibility-all]]</option>
|
||||
<option value="loggedin">[[admin/settings/reputation:vote-visibility-loggedin]]</option>
|
||||
<option value="privileged">[[admin/settings/reputation:vote-visibility-privileged]]</option>
|
||||
<label for="downvoteVisibility" class="form-check-label">[[admin/settings/reputation:downvote-visibility]]</label>
|
||||
<select id="downvoteVisibility" data-field="downvoteVisibility" class="form-select">
|
||||
<option value="all">[[admin/settings/reputation:downvote-visibility-all]]</option>
|
||||
<option value="loggedin">[[admin/settings/reputation:downvote-visibility-loggedin]]</option>
|
||||
<option value="privileged">[[admin/settings/reputation:downvote-visibility-privileged]]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary flip" data-option="-1" data-method="scaleX"><i class="fa fa-arrows-h"></i></button>
|
||||
<button class="btn btn-primary flip" data-option="1" data-method="scaleY"><i class="fa fa-arrows-v"></i></button>
|
||||
<button class="btn btn-primary flip" data-option="-1" data-method="scaleY"><i class="fa fa-arrows-v"></i></button>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary reset"><i class="fa fa-refresh"></i></button>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
{{{ if showUpvotes }}}
|
||||
<div class="mb-3">
|
||||
<h4>[[global:upvoters]] <small>({upvoteCount})</small></h4>
|
||||
{{{ each upvoters }}}
|
||||
<a class="text-decoration-none" href="{config.relative_path}/user/{./userslug}">{buildAvatar(@value, "24px", true)}</a>
|
||||
{{{ end }}}
|
||||
</div>
|
||||
{{{ end }}}
|
||||
{{{ if showDownvotes }}}
|
||||
<div>
|
||||
<h4>[[global:downvoters]] <small>({downvoteCount})</small></h4>
|
||||
|
||||
@@ -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>
|
||||
@@ -41,11 +41,13 @@ async function renderLocation(location, data, uid, options) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const renderedWidgets = await Promise.all(widgetsAtLocation.map(widget => renderWidget(widget, uid, options)));
|
||||
const renderedWidgets = await Promise.all(
|
||||
widgetsAtLocation.map(widget => renderWidget(widget, uid, options, location))
|
||||
);
|
||||
return renderedWidgets;
|
||||
}
|
||||
|
||||
async function renderWidget(widget, uid, options) {
|
||||
async function renderWidget(widget, uid, options, location) {
|
||||
if (!widget || !widget.data || (!!widget.data['hide-mobile'] && options.req.useragent.isMobile)) {
|
||||
return;
|
||||
}
|
||||
@@ -69,6 +71,7 @@ async function renderWidget(widget, uid, options) {
|
||||
data: widget.data,
|
||||
req: options.req,
|
||||
res: options.res,
|
||||
location,
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
|
||||
Reference in New Issue
Block a user