Skip to content

Commit

Permalink
Added query for fetching repost count (#305)
Browse files Browse the repository at this point in the history
Ref https://linear.app/ghost/issue/AP-706

- This adds a repost count so that the UI can display the count along with the repost icon
  • Loading branch information
vershwal authored Feb 6, 2025
1 parent c395ff6 commit d7fc758
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 2 deletions.
1 change: 1 addition & 0 deletions features/repost-activity.feature
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Feature: Reposting a post/note
When we repost the object "Note"
Then the request is accepted
And the object "Note" should be reposted
And the object "Note" should have a repost count of 1
And a "Announce(Note)" activity is sent to "Alice"

Scenario: Trying to repost a post/note that has already been reposted
Expand Down
20 changes: 20 additions & 0 deletions features/step_definitions/stepdefs.js
Original file line number Diff line number Diff line change
Expand Up @@ -800,6 +800,26 @@ Then('the object {string} should be reposted', async function (name) {
assert(found.object.reposted === true);
});

Then(
'the object {string} should have a repost count of {int}',
async function (name, repostCount) {
const response = await fetchActivityPub(
'http://fake-ghost-activitypub/.ghost/activitypub/inbox/index',
{
headers: {
Accept: 'application/ld+json',
},
},
);
const inbox = await response.json();
const object = this.objects[name];

const found = inbox.items.find((item) => item.object.id === object.id);

assert(found.object.repostCount === repostCount);
},
);

When('we undo the repost of the object {string}', async function (name) {
const id = this.objects[name].id;
this.response = await fetchActivityPub(
Expand Down
18 changes: 18 additions & 0 deletions src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,24 @@ export async function getActivityChildrenCount(activity: ActivityJsonLd) {
return result[0].count;
}

export async function getRepostCount(activity: ActivityJsonLd) {
const objectId = activity.object.id;

const result = await client
.count('* as count')
.from('key_value')
.where(function () {
this.where(
client.raw(
`JSON_EXTRACT(value, "$.object.id") = "${objectId}"`,
),
);
})
.andWhere(client.raw(`JSON_EXTRACT(value, "$.type") = "Announce"`));

return result[0].count;
}

export async function getActivityParents(activity: ActivityJsonLd) {
const parents: ActivityJsonLd[] = [];

Expand Down
5 changes: 3 additions & 2 deletions src/helpers/activitypub/activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { createHash } from 'node:crypto';
import { Announce, type Context, type KvStore, Like } from '@fedify/fedify';

import type { ContextData } from '../../app';
import { getActivityChildrenCount } from '../../db';
import { getActivityChildrenCount, getRepostCount } from '../../db';
import { lookupActor } from '../../lookup-helpers';
import { sanitizeHtml } from '../html';

Expand Down Expand Up @@ -132,9 +132,10 @@ export async function buildActivity(
}
}

// Add the reply count to the object, if it is an object
// Add reply count and repost count to the object, if it is an object
if (typeof item.object !== 'string') {
item.object.replyCount = await getActivityChildrenCount(item);
item.object.repostCount = await getRepostCount(item);
}

// Return the built item
Expand Down

0 comments on commit d7fc758

Please sign in to comment.