Files
NodeBB/public/src/client/category.js
2026-03-24 10:17:19 -04:00

162 lines
5.1 KiB
JavaScript

'use strict';
define('forum/category', [
'forum/infinitescroll',
'navigator',
'topicList',
'sort',
'categorySelector',
'hooks',
'alerts',
'api',
'clipboard',
], function (infinitescroll, navigator, topicList, sort, categorySelector, hooks, alerts, api, clipboard) {
const Category = {};
$(window).on('action:ajaxify.start', function (ev, data) {
if (!String(data.url).startsWith('category/')) {
navigator.disable();
}
});
Category.init = function () {
const cid = ajaxify.data.cid;
app.enterRoom('category_' + cid);
topicList.init('category', loadTopicsAfter);
sort.handleSort('categoryTopicSort', 'category/' + ajaxify.data.slug);
if (!config.usePagination) {
navigator.init('[component="category/topic"]', ajaxify.data.topic_count, Category.toTop, Category.toBottom);
} else {
navigator.disable();
}
handleScrollToTopicIndex();
handleIgnoreWatch(cid);
handleLoadMoreSubcategories();
handleDescription();
categorySelector.init($('[component="category-selector"]'), {
privilege: 'find',
parentCid: ajaxify.data.cid,
onSelect: function (category) {
ajaxify.go('/category/' + category.cid);
},
});
new clipboard('[data-clipboard-text]');
hooks.fire('action:topics.loaded', { topics: ajaxify.data.topics });
hooks.fire('action:category.loaded', { cid: ajaxify.data.cid });
};
function handleScrollToTopicIndex() {
let topicIndex = ajaxify.data.topicIndex;
if (topicIndex && utils.isNumber(topicIndex)) {
topicIndex = Math.max(0, parseInt(topicIndex, 10));
if (topicIndex && window.location.search.indexOf('page=') === -1) {
navigator.scrollToElement($('[component="category/topic"][data-index="' + topicIndex + '"]'), true, 0);
}
}
}
function handleIgnoreWatch(cid) {
$('[component="category/watching"], [component="category/tracking"], [component="category/ignoring"], [component="category/notwatching"]').on('click', function () {
const $this = $(this);
const state = $this.attr('data-state');
api.put(`/categories/${encodeURIComponent(cid)}/watch`, { state }, (err) => {
if (err) {
return alerts.error(err);
}
$('[component="category/watching/menu"]').toggleClass('hidden', state !== 'watching');
$('[component="category/watching/check"]').toggleClass('fa-check', state === 'watching');
$('[component="category/tracking/menu"]').toggleClass('hidden', state !== 'tracking');
$('[component="category/tracking/check"]').toggleClass('fa-check', state === 'tracking');
$('[component="category/notwatching/menu"]').toggleClass('hidden', state !== 'notwatching');
$('[component="category/notwatching/check"]').toggleClass('fa-check', state === 'notwatching');
$('[component="category/ignoring/menu"]').toggleClass('hidden', state !== 'ignoring');
$('[component="category/ignoring/check"]').toggleClass('fa-check', state === 'ignoring');
alerts.success('[[category:' + state + '.message]]');
});
});
}
function handleLoadMoreSubcategories() {
$('[component="category/load-more-subcategories"]').on('click', async function () {
const btn = $(this);
const { categories: data } = await api.get(`/categories/${ajaxify.data.cid}/children?start=${ajaxify.data.nextSubCategoryStart}`);
btn.toggleClass('hidden', !data.length || data.length < ajaxify.data.subCategoriesPerPage);
if (!data.length) {
return;
}
app.parseAndTranslate('category', 'children', { children: data }, function (html) {
html.find('.timeago').timeago();
$('[component="category/subcategory/container"]').append(html);
ajaxify.data.nextSubCategoryStart += ajaxify.data.subCategoriesPerPage;
ajaxify.data.subCategoriesLeft -= data.length;
btn.toggleClass('hidden', ajaxify.data.subCategoriesLeft <= 0)
.translateText('[[category:x-more-categories, ' + ajaxify.data.subCategoriesLeft + ']]');
});
return false;
});
}
function handleDescription() {
const fadeEl = $(`.description[class*="clamp-fade-"]`);
fadeEl.on('click', function () {
const $this = $(this);
let clampClass = $this.data('clampClass');
if (!clampClass) {
const match = $this.attr('class').match(/line-clamp-(\S+)/);
if (match && match[1]) {
clampClass = `line-clamp-${match[1]}`;
fadeEl.data('clampClass', clampClass);
}
}
if (clampClass) {
fadeEl.toggleClass(clampClass);
}
});
}
Category.toTop = function () {
navigator.scrollTop(0);
};
Category.toBottom = async () => {
const { count } = await api.get(`/categories/${encodeURIComponent(ajaxify.data.category.cid)}/count`);
navigator.scrollBottom(count - 1);
};
function loadTopicsAfter(after, direction, callback) {
callback = callback || function () {};
hooks.fire('action:topics.loading');
const params = utils.params();
infinitescroll.loadMore(`/categories/${encodeURIComponent(ajaxify.data.cid)}/topics`, {
after: after,
direction: direction,
query: params,
categoryTopicSort: params.sort || config.categoryTopicSort,
}, function (data, done) {
hooks.fire('action:topics.loaded', { topics: data.topics });
callback(data, done);
});
}
return Category;
});