mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46:12 +01:00
refactor: add placeholders on demand
remove emptylines/whitespace from tpls
This commit is contained in:
@@ -104,10 +104,10 @@
|
|||||||
"nodebb-plugin-ntfy": "1.7.4",
|
"nodebb-plugin-ntfy": "1.7.4",
|
||||||
"nodebb-plugin-spam-be-gone": "2.2.2",
|
"nodebb-plugin-spam-be-gone": "2.2.2",
|
||||||
"nodebb-rewards-essentials": "1.0.0",
|
"nodebb-rewards-essentials": "1.0.0",
|
||||||
"nodebb-theme-harmony": "1.2.57",
|
"nodebb-theme-harmony": "1.2.58",
|
||||||
"nodebb-theme-lavender": "7.1.8",
|
"nodebb-theme-lavender": "7.1.8",
|
||||||
"nodebb-theme-peace": "2.2.5",
|
"nodebb-theme-peace": "2.2.5",
|
||||||
"nodebb-theme-persona": "13.3.20",
|
"nodebb-theme-persona": "13.3.21",
|
||||||
"nodebb-widget-essentials": "7.0.16",
|
"nodebb-widget-essentials": "7.0.16",
|
||||||
"nodemailer": "6.9.13",
|
"nodemailer": "6.9.13",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ define('forum/topic/postTools', [
|
|||||||
if (!container) {
|
if (!container) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$('[component="topic"]').on('show.bs.dropdown', '.moderator-tools', function () {
|
$('[component="topic"]').on('show.bs.dropdown', '[component="post/tools"]', function () {
|
||||||
const $this = $(this);
|
const $this = $(this);
|
||||||
const dropdownMenu = $this.find('.dropdown-menu');
|
const dropdownMenu = $this.find('.dropdown-menu');
|
||||||
const { top } = this.getBoundingClientRect();
|
const { top } = this.getBoundingClientRect();
|
||||||
@@ -45,6 +45,10 @@ define('forum/topic/postTools', [
|
|||||||
if (dropdownMenu.attr('data-loaded')) {
|
if (dropdownMenu.attr('data-loaded')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
dropdownMenu.html(helpers.generatePlaceholderWave([
|
||||||
|
3, 5, 9, 7, 10, 'divider', 10,
|
||||||
|
]));
|
||||||
|
|
||||||
const postEl = $this.parents('[data-pid]');
|
const postEl = $this.parents('[data-pid]');
|
||||||
const pid = postEl.attr('data-pid');
|
const pid = postEl.attr('data-pid');
|
||||||
const index = parseInt(postEl.attr('data-index'), 10);
|
const index = parseInt(postEl.attr('data-index'), 10);
|
||||||
|
|||||||
@@ -8,21 +8,22 @@ define('forum/topic/replies', ['forum/topic/posts', 'hooks', 'alerts', 'api'], f
|
|||||||
const post = button.closest('[data-pid]');
|
const post = button.closest('[data-pid]');
|
||||||
const pid = post.data('pid');
|
const pid = post.data('pid');
|
||||||
const open = button.find('[component="post/replies/open"]');
|
const open = button.find('[component="post/replies/open"]');
|
||||||
const loading = button.find('[component="post/replies/loading"]');
|
|
||||||
const close = button.find('[component="post/replies/close"]');
|
|
||||||
|
|
||||||
if (open.is(':not(.hidden)') && loading.is('.hidden')) {
|
if (open.attr('loading') !== '1' && open.attr('loaded') !== '1') {
|
||||||
open.addClass('hidden');
|
open.attr('loading', '1')
|
||||||
loading.removeClass('hidden');
|
.removeClass('fa-chevron-down')
|
||||||
|
.addClass('fa-spin fa-spinner');
|
||||||
|
|
||||||
api.get(`/posts/${pid}/replies`, {}, function (err, { replies }) {
|
api.get(`/posts/${pid}/replies`, {}, function (err, { replies }) {
|
||||||
const postData = replies;
|
const postData = replies;
|
||||||
loading.addClass('hidden');
|
open.removeAttr('loading')
|
||||||
|
.attr('loaded', '1')
|
||||||
|
.removeClass('fa-spin fa-spinner')
|
||||||
|
.addClass('fa-chevron-up');
|
||||||
if (err) {
|
if (err) {
|
||||||
open.removeClass('hidden');
|
|
||||||
return alerts.error(err);
|
return alerts.error(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
close.removeClass('hidden');
|
|
||||||
postData.forEach((post, index) => {
|
postData.forEach((post, index) => {
|
||||||
if (post) {
|
if (post) {
|
||||||
post.index = index;
|
post.index = index;
|
||||||
@@ -50,10 +51,11 @@ define('forum/topic/replies', ['forum/topic/posts', 'hooks', 'alerts', 'api'], f
|
|||||||
hooks.fire('action:posts.loaded', { posts: postData });
|
hooks.fire('action:posts.loaded', { posts: postData });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else if (close.is(':not(.hidden)')) {
|
} else if (open.attr('loaded') === '1') {
|
||||||
close.addClass('hidden');
|
open.removeAttr('loaded')
|
||||||
open.removeClass('hidden');
|
.removeAttr('loading')
|
||||||
loading.addClass('hidden');
|
.removeClass('fa-spin fa-spinner fa-chevron-up')
|
||||||
|
.addClass('fa-chevron-down');
|
||||||
post.find('[component="post/replies"]').slideUp('fast', function () {
|
post.find('[component="post/replies"]').slideUp('fast', function () {
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ define('forum/topic/threadTools', [
|
|||||||
'bootbox',
|
'bootbox',
|
||||||
'alerts',
|
'alerts',
|
||||||
'bootstrap',
|
'bootstrap',
|
||||||
], function (components, translator, handleBack, posts, api, hooks, bootbox, alerts, bootstrap) {
|
'helpers',
|
||||||
|
], function (components, translator, handleBack, posts, api, hooks, bootbox, alerts, bootstrap, helpers) {
|
||||||
const ThreadTools = {};
|
const ThreadTools = {};
|
||||||
|
|
||||||
ThreadTools.init = function (tid, topicContainer) {
|
ThreadTools.init = function (tid, topicContainer) {
|
||||||
@@ -211,6 +212,7 @@ define('forum/topic/threadTools', [
|
|||||||
if (dropdownMenu.attr('data-loaded')) {
|
if (dropdownMenu.attr('data-loaded')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
dropdownMenu.html(helpers.generatePlaceholderWave([8, 8, 8]));
|
||||||
const data = await socket.emit('topics.loadTopicTools', { tid: ajaxify.data.tid, cid: ajaxify.data.cid });
|
const data = await socket.emit('topics.loadTopicTools', { tid: ajaxify.data.tid, cid: ajaxify.data.cid });
|
||||||
const html = await app.parseAndTranslate('partials/topic/topic-menu-list', data);
|
const html = await app.parseAndTranslate('partials/topic/topic-menu-list', data);
|
||||||
$(dropdownMenu).attr('data-loaded', 'true').html(html);
|
$(dropdownMenu).attr('data-loaded', 'true').html(html);
|
||||||
|
|||||||
@@ -25,12 +25,14 @@ module.exports = function (utils, Benchpress, relative_path) {
|
|||||||
userAgentIcons,
|
userAgentIcons,
|
||||||
buildAvatar,
|
buildAvatar,
|
||||||
increment,
|
increment,
|
||||||
|
generateWroteReplied,
|
||||||
generateRepliedTo,
|
generateRepliedTo,
|
||||||
generateWrote,
|
generateWrote,
|
||||||
isoTimeToLocaleString,
|
isoTimeToLocaleString,
|
||||||
shouldHideReplyContainer,
|
shouldHideReplyContainer,
|
||||||
humanReadableNumber,
|
humanReadableNumber,
|
||||||
formattedNumber,
|
formattedNumber,
|
||||||
|
generatePlaceholderWave,
|
||||||
register,
|
register,
|
||||||
__escape: identity,
|
__escape: identity,
|
||||||
};
|
};
|
||||||
@@ -295,34 +297,24 @@ module.exports = function (utils, Benchpress, relative_path) {
|
|||||||
if (!userObj) {
|
if (!userObj) {
|
||||||
userObj = this;
|
userObj = this;
|
||||||
}
|
}
|
||||||
|
classNames = classNames || '';
|
||||||
const attributes = new Map([
|
const attributes = new Map([
|
||||||
['alt', userObj.username],
|
|
||||||
['title', userObj.username],
|
['title', userObj.username],
|
||||||
['data-uid', userObj.uid],
|
['data-uid', userObj.uid],
|
||||||
['loading', 'lazy'],
|
['class', `avatar ${classNames}${rounded ? ' avatar-rounded' : ''}`],
|
||||||
['aria-label', `[[aria:user-avatar-for, ${userObj.username}]]`],
|
|
||||||
]);
|
]);
|
||||||
const styles = [`--avatar-size: ${size};`];
|
const styles = [`--avatar-size: ${size};`];
|
||||||
const attr2String = attributes => Array.from(attributes).reduce((output, [prop, value]) => {
|
const attr2String = attributes => Array.from(attributes).reduce((output, [prop, value]) => {
|
||||||
output += ` ${prop}="${value}"`;
|
output += ` ${prop}="${value}"`;
|
||||||
return output;
|
return output;
|
||||||
}, '');
|
}, '');
|
||||||
classNames = classNames || '';
|
|
||||||
|
|
||||||
attributes.set('class', `avatar ${classNames}${rounded ? ' avatar-rounded' : ''}`);
|
|
||||||
|
|
||||||
let output = '';
|
let output = '';
|
||||||
|
|
||||||
if (userObj.picture) {
|
if (userObj.picture) {
|
||||||
attributes.set('component', component || 'avatar/picture');
|
output += `<img${attr2String(attributes)} alt="${userObj.username}" loading="lazy" component="${component || 'avatar/picture'}" src="${userObj.picture}" style="${styles.join(' ')}" onError="this.remove()" itemprop="image" />`;
|
||||||
output += '<img ' + attr2String(attributes) + ' src="' + userObj.picture + '" style="' + styles.join(' ') + '" onError="this.remove();" itemprop="image" />';
|
|
||||||
}
|
}
|
||||||
|
output += `<span${attr2String(attributes)} component="${component || 'avatar/icon'}" style="${styles.join(' ')} background-color: ${userObj['icon:bgColor']}">${userObj['icon:text']}</span>`;
|
||||||
attributes.set('component', component || 'avatar/icon');
|
|
||||||
styles.push('background-color: ' + userObj['icon:bgColor'] + ';');
|
|
||||||
output += '<span ' + attr2String(attributes) + ' style="' + styles.join(' ') + '">' + userObj['icon:text'] + '</span>';
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,6 +322,13 @@ module.exports = function (utils, Benchpress, relative_path) {
|
|||||||
return String(value + parseInt(inc, 10));
|
return String(value + parseInt(inc, 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateWroteReplied(post, timeagoCutoff) {
|
||||||
|
if (post.toPid) {
|
||||||
|
return generateRepliedTo(post, timeagoCutoff);
|
||||||
|
}
|
||||||
|
return generateWrote(post, timeagoCutoff);
|
||||||
|
}
|
||||||
|
|
||||||
function generateRepliedTo(post, timeagoCutoff) {
|
function generateRepliedTo(post, timeagoCutoff) {
|
||||||
const displayname = post.parent && post.parent.displayname ?
|
const displayname = post.parent && post.parent.displayname ?
|
||||||
post.parent.displayname : '[[global:guest]]';
|
post.parent.displayname : '[[global:guest]]';
|
||||||
@@ -367,6 +366,21 @@ module.exports = function (utils, Benchpress, relative_path) {
|
|||||||
return utils.addCommas(number);
|
return utils.addCommas(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generatePlaceholderWave(items) {
|
||||||
|
const html = items.map((i) => {
|
||||||
|
if (i === 'divider') {
|
||||||
|
return '<li class="dropdown-divider"></li>';
|
||||||
|
}
|
||||||
|
return `
|
||||||
|
<li class="dropdown-item placeholder-wave">
|
||||||
|
<div class="placeholder" style="width: 20px;"></div>
|
||||||
|
<div class="placeholder col-${i}"></div>
|
||||||
|
</li>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
function register() {
|
function register() {
|
||||||
Object.keys(helpers).forEach(function (helperName) {
|
Object.keys(helpers).forEach(function (helperName) {
|
||||||
Benchpress.registerHelper(helperName, helpers[helperName]);
|
Benchpress.registerHelper(helperName, helpers[helperName]);
|
||||||
|
|||||||
@@ -89,7 +89,9 @@ apiController.loadConfig = async function (req) {
|
|||||||
size: meta.config.topicThumbSize,
|
size: meta.config.topicThumbSize,
|
||||||
},
|
},
|
||||||
emailPrompt: meta.config.emailPrompt,
|
emailPrompt: meta.config.emailPrompt,
|
||||||
useragent: req.useragent,
|
useragent: {
|
||||||
|
isSafari: req.useragent.isSafari,
|
||||||
|
},
|
||||||
fontawesome: {
|
fontawesome: {
|
||||||
pro: fontawesome_pro,
|
pro: fontawesome_pro,
|
||||||
styles: fontawesome_styles,
|
styles: fontawesome_styles,
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ async function compile() {
|
|||||||
let files = await plugins.getActive();
|
let files = await plugins.getActive();
|
||||||
files = await getTemplateDirs(files);
|
files = await getTemplateDirs(files);
|
||||||
files = await getTemplateFiles(files);
|
files = await getTemplateFiles(files);
|
||||||
|
const minify = process.env.NODE_ENV !== 'development';
|
||||||
await Promise.all(Object.keys(files).map(async (name) => {
|
await Promise.all(Object.keys(files).map(async (name) => {
|
||||||
const filePath = files[name];
|
const filePath = files[name];
|
||||||
let imported = await fs.promises.readFile(filePath, 'utf8');
|
let imported = await fs.promises.readFile(filePath, 'utf8');
|
||||||
@@ -122,6 +122,11 @@ async function compile() {
|
|||||||
|
|
||||||
await mkdirp(path.join(viewsPath, path.dirname(name)));
|
await mkdirp(path.join(viewsPath, path.dirname(name)));
|
||||||
|
|
||||||
|
// remove empty lines and whitespace
|
||||||
|
if (minify) {
|
||||||
|
imported = imported.split('\n').map(line => line.trim()).filter(Boolean).join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
await fs.promises.writeFile(path.join(viewsPath, name), imported);
|
await fs.promises.writeFile(path.join(viewsPath, name), imported);
|
||||||
const compiled = await Benchpress.precompile(imported, { filename: name });
|
const compiled = await Benchpress.precompile(imported, { filename: name });
|
||||||
await fs.promises.writeFile(path.join(viewsPath, name.replace(/\.tpl$/, '.js')), compiled);
|
await fs.promises.writeFile(path.join(viewsPath, name.replace(/\.tpl$/, '.js')), compiled);
|
||||||
|
|||||||
Reference in New Issue
Block a user