diff --git a/src/controllers/api/trends.ts b/src/controllers/api/trends.ts index 28132f6..7fc98e3 100644 --- a/src/controllers/api/trends.ts +++ b/src/controllers/api/trends.ts @@ -15,6 +15,7 @@ const trendingTagsController: AppController = (c) => { const yesterday = new Date(now.getTime() - Time.days(1)); const lastWeek = new Date(now.getTime() - Time.days(7)); + /** Most used hashtags within the past 24h. */ const tags = trends.getTrendingTags({ since: yesterday, until: now, @@ -25,6 +26,8 @@ const trendingTagsController: AppController = (c) => { name, url: Conf.local(`/tags/${name}`), history: [ + // Use the full 24h query for the current day. Then use `offset: 1` to adjust for this below. + // This result is more accurate than what Mastodon returns. { day: String(Math.floor(stripTime(now).getTime() / 1000)), accounts: String(accounts), @@ -37,6 +40,7 @@ const trendingTagsController: AppController = (c) => { limit: 6, offset: 1, }).map((history) => ({ + // For some reason, Mastodon wants these to be strings... oh well. day: String(Math.floor(history.day.getTime() / 1000)), accounts: String(history.accounts), uses: String(history.uses), diff --git a/src/trends.ts b/src/trends.ts index 8e941b0..3bb19d4 100644 --- a/src/trends.ts +++ b/src/trends.ts @@ -44,6 +44,7 @@ class TrendsDB { cleanup(); } + /** Gets the most used hashtags between the date range. */ getTrendingTags({ since, until, limit = 10, threshold = 3 }: GetTrendingTagsOpts) { return this.#db.query( ` @@ -63,6 +64,10 @@ class TrendsDB { })); } + /** + * Gets the tag usage count for a specific tag. + * It returns an array with counts for each date between the range. + */ getTagHistory({ tag, since, until, limit = 7, offset = 0 }: GetTagHistoryOpts) { const result = this.#db.query( ` @@ -81,11 +86,13 @@ class TrendsDB { uses: Number(row[2]), })); + /** Full date range between `since` and `until`. */ const dateRange = generateDateRange( new Date(since.getTime() + Time.days(1)), new Date(until.getTime() - Time.days(offset)), ).reverse(); + // Fill in missing dates with 0 usages. return dateRange.map((day) => { const data = result.find((item) => item.day.getTime() === day.getTime()); return data || { day, accounts: 0, uses: 0 };