diff --git a/.changeset/fresh-olives-vanish.md b/.changeset/fresh-olives-vanish.md new file mode 100644 index 00000000..4ff9048b --- /dev/null +++ b/.changeset/fresh-olives-vanish.md @@ -0,0 +1,7 @@ +--- +"@xmtp/react-sdk": minor +--- + +* Added `sentAt` field to cached reactions to track when a reaction was made +* Updated `getReactionsByXmtpID` to return reactions sorted by `sentAt` +* Updated `useReactions` hook to return reactions sorted by `sentAt` diff --git a/packages/react-sdk/src/helpers/caching/contentTypes/reaction.test.ts b/packages/react-sdk/src/helpers/caching/contentTypes/reaction.test.ts index 220f587f..fbe59ced 100644 --- a/packages/react-sdk/src/helpers/caching/contentTypes/reaction.test.ts +++ b/packages/react-sdk/src/helpers/caching/contentTypes/reaction.test.ts @@ -43,27 +43,39 @@ describe("ContentTypeReaction caching", () => { describe("saveReaction", () => { it("should save a reaction to the cache", async () => { + const firstSentAt = new Date(); const testReaction = { content: "test", referenceXmtpID: "testXmtpId", schema: "custom", senderAddress: "testWalletAddress", + sentAt: firstSentAt, xmtpID: "testXmtpId", } satisfies CachedReaction; const reactionId = await saveReaction(testReaction, db); expect(reactionId).toEqual(1); + const testReactions = await getReactionsByXmtpID("testXmtpId", db); + expect(testReactions.length).toEqual(1); + expect(testReactions[0].sentAt).toEqual(firstSentAt); + + const secondSentAt = new Date(); const testReaction2 = { content: "test", referenceXmtpID: "testXmtpId", schema: "custom", senderAddress: "testWalletAddress", + sentAt: secondSentAt, xmtpID: "testXmtpId", } satisfies CachedReaction; const reactionId2 = await saveReaction(testReaction2, db); expect(reactionId2).toEqual(1); + + const testReactions2 = await getReactionsByXmtpID("testXmtpId", db); + expect(testReactions2.length).toEqual(1); + expect(testReactions2[0].sentAt).toEqual(secondSentAt); }); }); diff --git a/packages/react-sdk/src/helpers/caching/contentTypes/reaction.ts b/packages/react-sdk/src/helpers/caching/contentTypes/reaction.ts index f71e6cb4..76a556f5 100644 --- a/packages/react-sdk/src/helpers/caching/contentTypes/reaction.ts +++ b/packages/react-sdk/src/helpers/caching/contentTypes/reaction.ts @@ -21,6 +21,7 @@ export type CachedReaction = { referenceXmtpID: Reaction["reference"]; schema: Reaction["schema"]; senderAddress: string; + sentAt: Date; xmtpID: string; }; @@ -75,6 +76,10 @@ export const saveReaction = async (reaction: CachedReaction, db: Dexie) => { // check if reaction already exists const existing = await findReaction(reaction, db); if (existing) { + // update when the reaction was sent + await reactionsTable.update(existing.id, { + sentAt: reaction.sentAt, + }); return existing.id; } @@ -108,7 +113,7 @@ export const getReactionsByXmtpID = async ( db: Dexie, ) => { const reactionsTable = db.table("reactions") as CachedReactionsTable; - return reactionsTable.where({ referenceXmtpID: xmtpID }).toArray(); + return reactionsTable.where({ referenceXmtpID: xmtpID }).sortBy("sentAt"); }; /** @@ -178,6 +183,7 @@ export const processReaction: ContentTypeMessageProcessor = async ({ referenceXmtpID: reaction.reference, schema: reaction.schema, senderAddress: message.senderAddress, + sentAt: message.sentAt, xmtpID: message.xmtpID, } satisfies CachedReaction; @@ -210,6 +216,7 @@ export const reactionContentTypeConfig: ContentTypeConfiguration = { content, schema, senderAddress, + sentAt, xmtpID `, }, diff --git a/packages/react-sdk/src/hooks/useReactions.ts b/packages/react-sdk/src/hooks/useReactions.ts index b0cc883f..06c31e93 100644 --- a/packages/react-sdk/src/hooks/useReactions.ts +++ b/packages/react-sdk/src/hooks/useReactions.ts @@ -17,7 +17,7 @@ export const useReactions = (message?: CachedMessage) => { return await reactionsTable .where("referenceXmtpID") .equals(message.xmtpID) - .toArray(); + .sortBy("sentAt"); } catch { return []; }