feat: #13255, deliver asserted topics to remote category followers

This commit is contained in:
Julian Lam
2025-03-20 13:02:30 -04:00
parent 6e23de46d6
commit 9c1d5cd36e
4 changed files with 49 additions and 10 deletions

View File

@@ -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,6 +420,12 @@ Actors.getLocalFollowers = async (id) => {
return response;
}
const [isUser, isCategory] = await Promise.all([
user.exists(id),
categories.exists(id),
]);
if (isUser) {
const members = await db.getSortedSetMembers(`followersRemote:${id}`);
members.forEach((id) => {
@@ -428,6 +435,12 @@ Actors.getLocalFollowers = async (id) => {
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;
};

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -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', () => {