From ebef8becc081e6c61d1e9da3515a1c0a383d8e9e Mon Sep 17 00:00:00 2001 From: capJavert Date: Thu, 16 Jan 2025 18:00:40 +0100 Subject: [PATCH 1/4] feat: add grouped argument so we can extract grouped dates --- src/schema/users.ts | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/schema/users.ts b/src/schema/users.ts index 62a45882b..f64caa86e 100644 --- a/src/schema/users.ts +++ b/src/schema/users.ts @@ -602,7 +602,7 @@ export const typeDefs = /* GraphQL */ ` } type ReadHistory { - date: DateTime! + date: String! reads: Int! } @@ -796,7 +796,16 @@ export const typeDefs = /* GraphQL */ ` """ Get a heatmap of reads per day in a given time frame. """ - userReadHistory(id: ID!, after: String!, before: String!): [ReadHistory] + userReadHistory( + id: ID! + after: String! + before: String! + + """ + Group by day stamp yyyy-MM-dd + """ + grouped: Boolean + ): [ReadHistory] """ Get the number of articles the user read """ @@ -1105,16 +1114,28 @@ export const getUserReadHistory = async ({ userId, after, before, + grouped, }: { con: DataSource; userId: string; after: Date; before: Date; + grouped?: boolean; }) => { - return con + const readHistoryQuery = con .getRepository(ActiveView) - .createQueryBuilder('view') - .select('view.timestamp', 'date') + .createQueryBuilder('view'); + + if (grouped) { + readHistoryQuery.select( + `date_trunc('day', view.timestamp)::date::text`, + 'date', + ); + } else { + readHistoryQuery.select('view.timestamp', 'date'); + } + + return readHistoryQuery .addSelect(`count(*) AS "reads"`) .innerJoin(User, 'user', 'user.id = view.userId') .where('view.userId = :userId', { userId }) @@ -1130,6 +1151,7 @@ interface ReadingHistyoryArgs { after: string; before: string; limit?: number; + grouped?: boolean; } interface userStreakProfileArgs { @@ -1443,7 +1465,7 @@ export const resolvers: IResolvers = traceResolvers< }, userReadHistory: async ( source, - { id, after, before }: ReadingHistyoryArgs, + { id, after, before, grouped }: ReadingHistyoryArgs, ctx: Context, ): Promise => getUserReadHistory({ @@ -1451,6 +1473,7 @@ export const resolvers: IResolvers = traceResolvers< userId: id, after: new Date(after), before: new Date(before), + grouped, }), userStreak: async ( _, From ad9f40e41656f190d78c33cd56db931e9e9db846 Mon Sep 17 00:00:00 2001 From: capJavert Date: Thu, 16 Jan 2025 18:04:30 +0100 Subject: [PATCH 2/4] feat: user timezone --- src/schema/users.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/schema/users.ts b/src/schema/users.ts index f64caa86e..89d151bf9 100644 --- a/src/schema/users.ts +++ b/src/schema/users.ts @@ -1128,7 +1128,7 @@ export const getUserReadHistory = async ({ if (grouped) { readHistoryQuery.select( - `date_trunc('day', view.timestamp)::date::text`, + `date_trunc('day', ${timestampAtTimezone})::date::text`, 'date', ); } else { From 8487b4c2d57e63bcee4c7aefc810722beebb7ebf Mon Sep 17 00:00:00 2001 From: capJavert Date: Thu, 16 Jan 2025 18:17:38 +0100 Subject: [PATCH 3/4] feat: format --- src/schema/users.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/schema/users.ts b/src/schema/users.ts index 89d151bf9..0360dcdc1 100644 --- a/src/schema/users.ts +++ b/src/schema/users.ts @@ -1132,7 +1132,11 @@ export const getUserReadHistory = async ({ 'date', ); } else { - readHistoryQuery.select('view.timestamp', 'date'); + // format to ISO 8601 because we can't use DateTime of gql due to grouped format + readHistoryQuery.select( + `to_char(view.timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')`, + 'date', + ); } return readHistoryQuery From 701cc149d5b1c6befda6718143ecd9db47ad6e3f Mon Sep 17 00:00:00 2001 From: capJavert Date: Thu, 16 Jan 2025 21:19:27 +0100 Subject: [PATCH 4/4] feat: minor adjustments --- src/schema/users.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/schema/users.ts b/src/schema/users.ts index 0360dcdc1..ddc5054bd 100644 --- a/src/schema/users.ts +++ b/src/schema/users.ts @@ -1133,10 +1133,13 @@ export const getUserReadHistory = async ({ ); } else { // format to ISO 8601 because we can't use DateTime of gql due to grouped format - readHistoryQuery.select( - `to_char(view.timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')`, - 'date', - ); + readHistoryQuery + .select( + `to_char(view.timestamp, 'YYYY-MM-DD"T"HH24:MI:SS.MS"Z"')`, + 'date', + ) + // limit to 30 events for ungrouped views, reading streak + .limit(30); } return readHistoryQuery