mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-26 16:46: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) => {
|
Actors.getLocalFollowers = async (id) => {
|
||||||
|
// Returns local uids and cids that follow a remote actor (by id)
|
||||||
const response = {
|
const response = {
|
||||||
uids: new Set(),
|
uids: new Set(),
|
||||||
cids: new Set(),
|
cids: new Set(),
|
||||||
@@ -419,15 +420,27 @@ Actors.getLocalFollowers = async (id) => {
|
|||||||
return response;
|
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 (isUser) {
|
||||||
if (utils.isNumber(id)) {
|
const members = await db.getSortedSetMembers(`followersRemote:${id}`);
|
||||||
response.uids.add(parseInt(id, 10));
|
|
||||||
} else if (id.startsWith('cid|') && utils.isNumber(id.slice(4))) {
|
members.forEach((id) => {
|
||||||
response.cids.add(parseInt(id.slice(4), 10));
|
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;
|
return response;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -462,6 +462,12 @@ Notes.syncUserInboxes = async function (tid, uid) {
|
|||||||
uids.add(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 keys = Array.from(uids).map(uid => `uid:${uid}:inbox`);
|
||||||
const score = await db.sortedSetScore(`cid:${cid}:tids`, tid);
|
const score = await db.sortedSetScore(`cid:${cid}:tids`, tid);
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,12 @@ User.exists = async function (uids) {
|
|||||||
const singular = !Array.isArray(uids);
|
const singular = !Array.isArray(uids);
|
||||||
uids = singular ? [uids] : uids;
|
uids = singular ? [uids] : uids;
|
||||||
|
|
||||||
let results = await Promise.all(uids.map(async uid => await db.isMemberOfSortedSets(['users:joindate', 'usersRemote:lastCrawled'], uid)));
|
const local = await db.isSortedSetMembers('users:joindate', uids);
|
||||||
results = results.map(set => set.some(Boolean));
|
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;
|
return singular ? results.pop() : results;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -109,6 +109,22 @@ describe('Notes', () => {
|
|||||||
assert.strictEqual(category[prop], 1);
|
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', () => {
|
describe('User-specific behaviours', () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user