diff --git a/install/data/defaults.json b/install/data/defaults.json
index 449234192c..fcbac89921 100644
--- a/install/data/defaults.json
+++ b/install/data/defaults.json
@@ -206,5 +206,7 @@
"activitypubProbeTimeout": 2000,
"activitypubContentPruneDays": 30,
"activitypubUserPruneDays": 7,
- "activitypubFilter": 0
+ "activitypubFilter": 0,
+ "activitypubSummaryLimit": 500,
+ "activitypubBreakString": "[...]"
}
diff --git a/public/language/en-GB/admin/menu.json b/public/language/en-GB/admin/menu.json
index 319e4d3af2..9a2566141e 100644
--- a/public/language/en-GB/admin/menu.json
+++ b/public/language/en-GB/admin/menu.json
@@ -50,9 +50,10 @@
"section-federation": "Federation",
"federation/general": "General",
+ "federation/content": "Content",
"federation/rules": "Categorization",
"federation/relays": "Relays",
- "federation/pruning": "Content Pruning",
+ "federation/pruning": "Storage",
"federation/safety": "Trust & Safety",
"section-appearance": "Appearance",
diff --git a/public/language/en-GB/admin/settings/activitypub.json b/public/language/en-GB/admin/settings/activitypub.json
index 5ab4fa43e8..0486870db1 100644
--- a/public/language/en-GB/admin/settings/activitypub.json
+++ b/public/language/en-GB/admin/settings/activitypub.json
@@ -44,5 +44,11 @@
"count": "This NodeBB is currently aware of %1 server(s)",
"server.filter-help": "Specify servers you would like to bar from federating with your NodeBB. Alternatively, you may opt to selectively allow federation with specific servers, instead. Both options are supported, although they are mutually exclusive.",
"server.filter-help-hostname": "Enter just the instance hostname below (e.g. example.org), separated by line breaks.",
- "server.filter-allow-list": "Use this as an Allow List instead"
+ "server.filter-allow-list": "Use this as an Allow List instead",
+
+ "content.outgoing": "Outgoing",
+ "content.summary-limit": "Character count after which a summary is generated",
+ "content.summary-limit-help": "When content is federated out that exceeds this character count, a summary is generated, comprising of all complete sentences prior to this limit. (Default: 500)",
+ "content.break-string": "Note/Article Delimiter",
+ "content.break-string-help": "This delimiter can be manually inserted by power users when composing new topics. It instructs NodeBB to use content up until that point as part of the summary. If this string is not used, then the character count fallback applies. (Default: [...])"
}
\ No newline at end of file
diff --git a/src/activitypub/mocks.js b/src/activitypub/mocks.js
index 793bf9d8fd..6eef6d2665 100644
--- a/src/activitypub/mocks.js
+++ b/src/activitypub/mocks.js
@@ -8,6 +8,7 @@ const sanitize = require('sanitize-html');
const tokenizer = require('sbd');
const db = require('../database');
+const meta = require('../meta');
const user = require('../user');
const categories = require('../categories');
const posts = require('../posts');
@@ -710,7 +711,7 @@ Mocks.notes.public = async (post) => {
// Special handling for main posts (as:Article w/ as:Note preview)
const plaintext = posts.sanitizePlaintext(content);
- const isArticle = post.pid === post.topic.mainPid && plaintext.length > 500;
+ const isArticle = post.pid === post.topic.mainPid && plaintext.length > meta.config.activitypubSummaryLimit;
if (post.isMainPost) {
const thumbs = await topics.thumbs.get(post.tid);
@@ -755,17 +756,16 @@ Mocks.notes.public = async (post) => {
// attachment,
// };
- const breakString = '[...]';
- if (post.content.includes(breakString)) {
- const index = post.content.indexOf(breakString);
- summary = post.content.slice(0, index + breakString.length);
+ if (post.content.includes(meta.config.activitypubBreakString)) {
+ const index = post.content.indexOf(meta.config.activitypubBreakString);
+ summary = post.content.slice(0, index + meta.config.activitypubBreakString.length);
} else {
const sentences = tokenizer.sentences(post.content, { newline_boundaries: true });
- // Append sentences to summary until it contains just under 500 characters of content
- const limit = 500;
+ // Append sentences to summary until until just under configured character limit
+ const limit = meta.config.activitypubSummaryLimit;
let remaining = limit;
let finished = false;
- summary = sentences.reduce((memo, sentence) => {
+ summary = sentences.reduce((memo, sentence, index) => {
if (finished) {
return memo;
}
@@ -776,7 +776,7 @@ Mocks.notes.public = async (post) => {
});
remaining = remaining - clean.length;
if (remaining > 0) {
- memo += ` ${sentence}`;
+ memo += `${index > 0 ? ' ' : ''}${sentence}`;
} else { // There was more but summary generation is complete
finished = true;
memo += ' [...]';
diff --git a/src/controllers/admin/federation.js b/src/controllers/admin/federation.js
index 4d6cd104a4..ec6b93c35e 100644
--- a/src/controllers/admin/federation.js
+++ b/src/controllers/admin/federation.js
@@ -10,6 +10,12 @@ federationController.general = function (req, res) {
});
};
+federationController.content = function (req, res) {
+ res.render(`admin/federation/content`, {
+ title: '[[admin/menu:federation/content]]',
+ });
+};
+
federationController.rules = async function (req, res) {
const rules = await activitypub.rules.list();
diff --git a/src/posts/parse.js b/src/posts/parse.js
index 37cdd52c9c..a4d8f57443 100644
--- a/src/posts/parse.js
+++ b/src/posts/parse.js
@@ -58,7 +58,7 @@ module.exports = function (Posts) {
}
if (!type.startsWith('activitypub.')) {
- postData.content = postData.content.replace('[...]', '');
+ postData.content = postData.content.replace(meta.config.activitypubBreakString, '');
}
({ postData } = await plugins.hooks.fire('filter:parse.post', { postData, type }));
postData.content = translator.escape(postData.content);
diff --git a/src/routes/admin.js b/src/routes/admin.js
index bca37af2ce..d00abd0056 100644
--- a/src/routes/admin.js
+++ b/src/routes/admin.js
@@ -53,6 +53,7 @@ module.exports = function (app, name, middleware, controllers) {
helpers.setupAdminPageRoute(app, `/${name}/settings/advanced`, middlewares, controllers.admin.settings.advanced);
helpers.setupAdminPageRoute(app, `/${name}/federation/general`, middlewares, controllers.admin.federation.general);
+ helpers.setupAdminPageRoute(app, `/${name}/federation/content`, middlewares, controllers.admin.federation.content);
helpers.setupAdminPageRoute(app, `/${name}/federation/rules`, middlewares, controllers.admin.federation.rules);
helpers.setupAdminPageRoute(app, `/${name}/federation/relays`, middlewares, controllers.admin.federation.relays);
helpers.setupAdminPageRoute(app, `/${name}/federation/pruning`, middlewares, controllers.admin.federation.pruning);
diff --git a/src/views/admin/federation/content.tpl b/src/views/admin/federation/content.tpl
new file mode 100644
index 0000000000..3ee43fcf21
--- /dev/null
+++ b/src/views/admin/federation/content.tpl
@@ -0,0 +1,29 @@
+