From 41c2ed8e9c5064e80cc662f6a1cd677dfb9092f0 Mon Sep 17 00:00:00 2001 From: Fabilin Date: Mon, 23 Jun 2025 11:35:09 +0200 Subject: [PATCH 1/3] resolves #190: add historyMaxAge parameter --- README.md | 11 ++++++----- src/settings/TockSettings.tsx | 2 ++ src/useTock.ts | 21 +++++++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 3ac0e38..f854a37 100644 --- a/README.md +++ b/README.md @@ -352,11 +352,12 @@ Objects implementing this interface can be passed to `renderChat` or to `TockCon #### `LocalStorageSettings` -| Property name | Type | Description | -|------------------------|------------|---------------------------------------------------------------------------------------------------------------------------------------------| -| `enableMessageHistory` | `boolean?` | If set to `true`, the most recent messages of a conversation will be persisted in the local storage. Defaults to `false`. | -| `maxMessageCount` | `number?` | When message history is enabled, sets the max number of messages to store. Defaults to 10. | -| `prefix` | `string?` | Prefix for local storage keys allowing communication with different bots from the same domain (used for both `userId` and message history). | +| Property name | Type | Description | +|------------------------|------------|------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `enableMessageHistory` | `boolean?` | If set to `true`, the most recent messages of a conversation will be persisted in the local storage. Defaults to `false`. | +| `historyMaxAge` | `number?` | If set to a positive value, represents the number of seconds before the message history is cleared (the timeout is reset after each message received). | +| `maxMessageCount` | `number?` | When message history is enabled, sets the max number of messages to store. Defaults to 10. | +| `prefix` | `string?` | Prefix for local storage keys allowing communication with different bots from the same domain (used for both `userId` and message history). | #### `NetworkSettings` diff --git a/src/settings/TockSettings.tsx b/src/settings/TockSettings.tsx index 021d7dd..6de9e66 100644 --- a/src/settings/TockSettings.tsx +++ b/src/settings/TockSettings.tsx @@ -6,6 +6,7 @@ export interface LocalStorageSettings { prefix: string; enableMessageHistory: boolean; maxMessageCount: number; + historyMaxAge: number; } export interface NetworkSettings { @@ -28,6 +29,7 @@ export const defaultSettings: TockSettings = { prefix: '', enableMessageHistory: false, maxMessageCount: 10, + historyMaxAge: -1, }, network: { disableSse: false, diff --git a/src/useTock.ts b/src/useTock.ts index 68f0b1f..1faa8a0 100644 --- a/src/useTock.ts +++ b/src/useTock.ts @@ -179,6 +179,10 @@ export const useTock0: ( localStoragePrefix, 'tockMessageHistory', ); + const messageHistoryLastTime = retrievePrefixedLocalStorageKey( + localStoragePrefix, + 'tockLastMessageTimestamp', + ); const savedHistory = window.localStorage.getItem(messageHistoryLSKeyName); let history: Message[]; @@ -195,6 +199,7 @@ export const useTock0: ( messageHistoryLSKeyName, JSON.stringify(history), ); + window.localStorage.setItem(messageHistoryLastTime, '' + Date.now()); }, [localStoragePrefix, localStorageMaxMessages], ); @@ -652,6 +657,10 @@ export const useTock0: ( localStoragePrefix, 'tockHandledResponses', ); + const messageHistoryLastTimeKey = retrievePrefixedLocalStorageKey( + localStoragePrefix, + 'tockLastMessageTimestamp', + ); const serializedHistory = storageAvailable('localStorage') && localStorageEnabled @@ -659,6 +668,18 @@ export const useTock0: ( : undefined; if (serializedHistory) { + const historyMaxAge = localStorageSettings.historyMaxAge; + if (historyMaxAge > 0) { + const lastMessageTime = + window.localStorage.getItem(messageHistoryLastTimeKey) ?? 0; + if (historyMaxAge > (Date.now() - +lastMessageTime) / 1000) { + window.localStorage.removeItem(messageHistoryLSKey); + window.localStorage.removeItem(quickReplyHistoryLSKey); + window.localStorage.removeItem(messageHistoryLastTimeKey); + return null; + } + } + const messages = JSON.parse(serializedHistory); const quickReplies = JSON.parse( window.localStorage.getItem(quickReplyHistoryLSKey) || '[]', From 94b0392b8fec823bf25a020fe2a51e103112e5ef Mon Sep 17 00:00:00 2001 From: Fabilin Date: Wed, 25 Jun 2025 14:26:49 +0200 Subject: [PATCH 2/3] clean up type conversion --- src/useTock.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/useTock.ts b/src/useTock.ts index 1faa8a0..f54746c 100644 --- a/src/useTock.ts +++ b/src/useTock.ts @@ -670,9 +670,10 @@ export const useTock0: ( if (serializedHistory) { const historyMaxAge = localStorageSettings.historyMaxAge; if (historyMaxAge > 0) { - const lastMessageTime = - window.localStorage.getItem(messageHistoryLastTimeKey) ?? 0; - if (historyMaxAge > (Date.now() - +lastMessageTime) / 1000) { + const lastMessageTime = +( + window.localStorage.getItem(messageHistoryLastTimeKey) ?? 0 + ); + if (historyMaxAge > (Date.now() - lastMessageTime) / 1000) { window.localStorage.removeItem(messageHistoryLSKey); window.localStorage.removeItem(quickReplyHistoryLSKey); window.localStorage.removeItem(messageHistoryLastTimeKey); From 67f0075b39c1faf03fa56bb1dc4548fd5d2fee0c Mon Sep 17 00:00:00 2001 From: Fabilin Date: Wed, 2 Jul 2025 09:48:43 +0200 Subject: [PATCH 3/3] fix comparison --- src/useTock.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/useTock.ts b/src/useTock.ts index f54746c..c69222a 100644 --- a/src/useTock.ts +++ b/src/useTock.ts @@ -673,7 +673,7 @@ export const useTock0: ( const lastMessageTime = +( window.localStorage.getItem(messageHistoryLastTimeKey) ?? 0 ); - if (historyMaxAge > (Date.now() - lastMessageTime) / 1000) { + if ((Date.now() - lastMessageTime) / 1000 > historyMaxAge) { window.localStorage.removeItem(messageHistoryLSKey); window.localStorage.removeItem(quickReplyHistoryLSKey); window.localStorage.removeItem(messageHistoryLastTimeKey);