mirror of
https://github.com/NodeBB/NodeBB.git
synced 2026-03-03 19:11:22 +01:00
feat: quick create on world page
This commit removes title requirement checks in NodeBB and updates the topic creation logic so that incoming topic creation API requests without a title just generate a title (like they already do for incoming AP content.)
This commit is contained in:
@@ -254,6 +254,7 @@
|
|||||||
"no-more-next-post": "You don't have more posts in this topic",
|
"no-more-next-post": "You don't have more posts in this topic",
|
||||||
"open-composer": "Open composer",
|
"open-composer": "Open composer",
|
||||||
"post-quick-reply": "Quick reply",
|
"post-quick-reply": "Quick reply",
|
||||||
|
"post-quick-create": "Quick post",
|
||||||
|
|
||||||
"navigator.index": "Post %1 of %2",
|
"navigator.index": "Post %1 of %2",
|
||||||
"navigator.unread": "%1 unread",
|
"navigator.unread": "%1 unread",
|
||||||
|
|||||||
@@ -3,8 +3,10 @@
|
|||||||
define('forum/world', [
|
define('forum/world', [
|
||||||
'forum/infinitescroll', 'search', 'sort', 'hooks',
|
'forum/infinitescroll', 'search', 'sort', 'hooks',
|
||||||
'alerts', 'api', 'bootbox', 'helpers', 'forum/category/tools',
|
'alerts', 'api', 'bootbox', 'helpers', 'forum/category/tools',
|
||||||
'translator',
|
'translator', 'quickreply',
|
||||||
], function (infinitescroll, search, sort, hooks, alerts, api, bootbox, helpers, categoryTools, translator) {
|
], function (infinitescroll, search, sort, hooks,
|
||||||
|
alerts, api, bootbox, helpers, categoryTools,
|
||||||
|
translator, quickreply) {
|
||||||
const World = {};
|
const World = {};
|
||||||
|
|
||||||
$(window).on('action:ajaxify.start', function () {
|
$(window).on('action:ajaxify.start', function () {
|
||||||
@@ -14,6 +16,7 @@ define('forum/world', [
|
|||||||
World.init = function () {
|
World.init = function () {
|
||||||
app.enterRoom('world');
|
app.enterRoom('world');
|
||||||
categoryTools.init($('#world-feed'));
|
categoryTools.init($('#world-feed'));
|
||||||
|
quickreply.init();
|
||||||
|
|
||||||
sort.handleSort('categoryTopicSort', 'world');
|
sort.handleSort('categoryTopicSort', 'world');
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,18 @@ define('quickreply', [
|
|||||||
handle: undefined,
|
handle: undefined,
|
||||||
content: replyMsg,
|
content: replyMsg,
|
||||||
};
|
};
|
||||||
|
let replyRoute = '/topics';
|
||||||
|
switch(ajaxify.data.template.name) {
|
||||||
|
case 'topic':
|
||||||
|
replyData.tid = ajaxify.data.tid;
|
||||||
|
replyRoute = `/topics/${ajaxify.data.tid}`;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'world':
|
||||||
|
replyData.cid = '-1';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
const replyLen = replyMsg.length;
|
const replyLen = replyMsg.length;
|
||||||
if (replyLen < parseInt(config.minimumPostLength, 10)) {
|
if (replyLen < parseInt(config.minimumPostLength, 10)) {
|
||||||
return alerts.error('[[error:content-too-short, ' + config.minimumPostLength + ']]');
|
return alerts.error('[[error:content-too-short, ' + config.minimumPostLength + ']]');
|
||||||
@@ -78,7 +90,7 @@ define('quickreply', [
|
|||||||
|
|
||||||
ready = false;
|
ready = false;
|
||||||
element.val('');
|
element.val('');
|
||||||
api.post(`/topics/${ajaxify.data.tid}`, replyData, function (err, data) {
|
api.post(replyRoute, replyData, function (err, data) {
|
||||||
ready = true;
|
ready = true;
|
||||||
if (err) {
|
if (err) {
|
||||||
element.val(replyMsg);
|
element.val(replyMsg);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const user = require('../../user');
|
|||||||
const topics = require('../../topics');
|
const topics = require('../../topics');
|
||||||
const posts = require('../../posts');
|
const posts = require('../../posts');
|
||||||
const categories = require('../../categories');
|
const categories = require('../../categories');
|
||||||
|
const privileges = require('../../privileges');
|
||||||
const translator = require('../../translator');
|
const translator = require('../../translator');
|
||||||
const pagination = require('../../pagination');
|
const pagination = require('../../pagination');
|
||||||
const utils = require('../../utils');
|
const utils = require('../../utils');
|
||||||
@@ -24,7 +25,10 @@ controller.list = async function (req, res) {
|
|||||||
const start = Math.max(0, (page - 1) * topicsPerPage);
|
const start = Math.max(0, (page - 1) * topicsPerPage);
|
||||||
const stop = start + topicsPerPage - 1;
|
const stop = start + topicsPerPage - 1;
|
||||||
|
|
||||||
const userSettings = await user.getSettings(req.uid);
|
const [userSettings, userPrivileges] = await Promise.all([
|
||||||
|
user.getSettings(req.uid),
|
||||||
|
privileges.categories.get('-1', req.uid),
|
||||||
|
]);
|
||||||
const targetUid = await user.getUidByUserslug(req.query.author);
|
const targetUid = await user.getUidByUserslug(req.query.author);
|
||||||
let cidQuery = {
|
let cidQuery = {
|
||||||
uid: req.uid,
|
uid: req.uid,
|
||||||
@@ -40,6 +44,7 @@ controller.list = async function (req, res) {
|
|||||||
const data = await categories.getCategoryById(cidQuery);
|
const data = await categories.getCategoryById(cidQuery);
|
||||||
delete data.children;
|
delete data.children;
|
||||||
data.sort = req.query.sort;
|
data.sort = req.query.sort;
|
||||||
|
data.privileges = userPrivileges;
|
||||||
|
|
||||||
let tids;
|
let tids;
|
||||||
let topicCount;
|
let topicCount;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const { setupApiRoute } = routeHelpers;
|
|||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
const middlewares = [middleware.ensureLoggedIn];
|
const middlewares = [middleware.ensureLoggedIn];
|
||||||
|
|
||||||
setupApiRoute(router, 'post', '/', [middleware.checkRequired.bind(null, ['cid', 'title', 'content'])], controllers.write.topics.create);
|
setupApiRoute(router, 'post', '/', [middleware.checkRequired.bind(null, ['cid', 'content'])], controllers.write.topics.create);
|
||||||
setupApiRoute(router, 'get', '/:tid', [], controllers.write.topics.get);
|
setupApiRoute(router, 'get', '/:tid', [], controllers.write.topics.get);
|
||||||
setupApiRoute(router, 'post', '/:tid', [middleware.checkRequired.bind(null, ['content']), middleware.assert.topic], controllers.write.topics.reply);
|
setupApiRoute(router, 'post', '/:tid', [middleware.checkRequired.bind(null, ['content']), middleware.assert.topic], controllers.write.topics.reply);
|
||||||
setupApiRoute(router, 'delete', '/:tid', [...middlewares], controllers.write.topics.purge);
|
setupApiRoute(router, 'delete', '/:tid', [...middlewares], controllers.write.topics.purge);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const winston = require('winston');
|
const winston = require('winston');
|
||||||
|
const tokenizer = require('sbd');
|
||||||
|
|
||||||
const db = require('../database');
|
const db = require('../database');
|
||||||
const utils = require('../utils');
|
const utils = require('../utils');
|
||||||
@@ -102,9 +103,17 @@ module.exports = function (Topics) {
|
|||||||
privileges.users.isAdministrator(uid),
|
privileges.users.isAdministrator(uid),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
data.title = String(data.title).trim();
|
|
||||||
data.tags = data.tags || [];
|
data.tags = data.tags || [];
|
||||||
data.content = String(data.content || '').trimEnd();
|
data.content = String(data.content || '').trimEnd();
|
||||||
|
|
||||||
|
if (data.title) {
|
||||||
|
data.title = String(data.title).trim();
|
||||||
|
} else {
|
||||||
|
const sentences = tokenizer.sentences(data.content, { sanitize: true, newline_boundaries: true });
|
||||||
|
data.title = sentences.shift();
|
||||||
|
data.generatedTitle = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
Topics.checkTitle(data.title);
|
Topics.checkTitle(data.title);
|
||||||
}
|
}
|
||||||
@@ -259,6 +268,7 @@ module.exports = function (Topics) {
|
|||||||
Topics.addParentPosts([postData], uid),
|
Topics.addParentPosts([postData], uid),
|
||||||
Topics.syncBacklinks(postData),
|
Topics.syncBacklinks(postData),
|
||||||
Topics.markAsRead([tid], uid),
|
Topics.markAsRead([tid], uid),
|
||||||
|
activitypub.notes.syncUserInboxes(tid, uid),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Returned data is a superset of post summary data
|
// Returned data is a superset of post summary data
|
||||||
|
|||||||
Reference in New Issue
Block a user