mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 08:36:12 +01:00
feat: #13255, deliver asserted topics to remote category followers
This commit is contained in:
@@ -410,6 +410,7 @@ async function _migratePersonToGroup(categoryObjs) {
|
||||
}
|
||||
|
||||
Actors.getLocalFollowers = async (id) => {
|
||||
// Returns local uids and cids that follow a remote actor (by id)
|
||||
const response = {
|
||||
uids: new Set(),
|
||||
cids: new Set(),
|
||||
@@ -419,15 +420,27 @@ Actors.getLocalFollowers = async (id) => {
|
||||
return response;
|
||||
}
|
||||
|
||||
const members = await db.getSortedSetMembers(`followersRemote:${id}`);
|
||||
const [isUser, isCategory] = await Promise.all([
|
||||
user.exists(id),
|
||||
categories.exists(id),
|
||||
]);
|
||||
|
||||
members.forEach((id) => {
|
||||
if (utils.isNumber(id)) {
|
||||
response.uids.add(parseInt(id, 10));
|
||||
} else if (id.startsWith('cid|') && utils.isNumber(id.slice(4))) {
|
||||
response.cids.add(parseInt(id.slice(4), 10));
|
||||
}
|
||||
});
|
||||
if (isUser) {
|
||||
const members = await db.getSortedSetMembers(`followersRemote:${id}`);
|
||||
|
||||
members.forEach((id) => {
|
||||
if (utils.isNumber(id)) {
|
||||
response.uids.add(parseInt(id, 10));
|
||||
} else if (id.startsWith('cid|') && utils.isNumber(id.slice(4))) {
|
||||
response.cids.add(parseInt(id.slice(4), 10));
|
||||
}
|
||||
});
|
||||
} else if (isCategory) {
|
||||
const members = await db.getSortedSetRangeByScore(`cid:${id}:uid:watch:state`, 0, -1, categories.watchStates.tracking, categories.watchStates.watching);
|
||||
members.forEach((uid) => {
|
||||
response.uids.add(uid);
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
@@ -462,6 +462,12 @@ Notes.syncUserInboxes = async function (tid, uid) {
|
||||
uids.add(uid);
|
||||
});
|
||||
|
||||
// Category followers
|
||||
const categoryFollowers = await activitypub.actors.getLocalFollowers(cid);
|
||||
categoryFollowers.uids.forEach((uid) => {
|
||||
uids.add(uid);
|
||||
});
|
||||
|
||||
const keys = Array.from(uids).map(uid => `uid:${uid}:inbox`);
|
||||
const score = await db.sortedSetScore(`cid:${cid}:tids`, tid);
|
||||
|
||||
|
||||
@@ -46,8 +46,12 @@ User.exists = async function (uids) {
|
||||
const singular = !Array.isArray(uids);
|
||||
uids = singular ? [uids] : uids;
|
||||
|
||||
let results = await Promise.all(uids.map(async uid => await db.isMemberOfSortedSets(['users:joindate', 'usersRemote:lastCrawled'], uid)));
|
||||
results = results.map(set => set.some(Boolean));
|
||||
const local = await db.isSortedSetMembers('users:joindate', uids);
|
||||
const remote = await db.exists(uids.map(uid => `userRemote:${uid}`));
|
||||
const results = local.map((a, idx) => {
|
||||
const b = remote[idx];
|
||||
return a || b;
|
||||
});
|
||||
|
||||
return singular ? results.pop() : results;
|
||||
};
|
||||
|
||||
@@ -109,6 +109,22 @@ describe('Notes', () => {
|
||||
assert.strictEqual(category[prop], 1);
|
||||
});
|
||||
});
|
||||
|
||||
it('should add a remote category topic to a user\'s inbox if they are following the category', async () => {
|
||||
const { id: cid, actor } = helpers.mocks.group();
|
||||
await activitypub.actors.assertGroup([cid]);
|
||||
|
||||
const uid = await user.create({ username: utils.generateUUID() });
|
||||
await api.categories.setWatchState({ uid }, { cid, state: categories.watchStates.tracking });
|
||||
|
||||
const { id } = helpers.mocks.note({
|
||||
cc: [cid],
|
||||
});
|
||||
const { tid } = await activitypub.notes.assert(0, id);
|
||||
|
||||
const inInbox = await db.isSortedSetMember(`uid:${uid}:inbox`, tid);
|
||||
assert(inInbox);
|
||||
});
|
||||
});
|
||||
|
||||
describe('User-specific behaviours', () => {
|
||||
|
||||
Reference in New Issue
Block a user