Update StoryEditorClient with new API key dependency

This commit is contained in:
Riccardo Giorato
2026-01-06 13:45:42 +01:00
parent 120d011f06
commit f4bb681e05
4 changed files with 24 additions and 59 deletions
@@ -67,6 +67,7 @@ export function StoryEditorClient() {
const { toast } = useToast();
const [apiKey, setApiKey] = useApiKey();
const handleTitleUpdate = (newTitle: string) => {
setStory(prev => prev ? { ...prev, title: newTitle } : null);
};
@@ -166,12 +167,14 @@ export function StoryEditorClient() {
window.addEventListener("keydown", handleKeyDown);
return () => window.removeEventListener("keydown", handleKeyDown);
}, [pages.length]);
}, [pages.length, apiKey]);
const handleAddPage = () => {
if (!isLoaded || !isSignedIn) {
return;
}
if (!apiKey && pages.length >= 1) {
setShowApiModal(true);
return;
+4 -58
View File
@@ -1,65 +1,11 @@
"use client";
import { useState, useEffect, useCallback } from "react";
import useLocalStorageState from "use-local-storage-state";
const STORAGE_KEY = "together_api_key";
const STORAGE_EVENT = "apiKeyChanged";
/**
* Reactive hook for managing the Together API key in localStorage.
* Automatically syncs across components and tabs when the key changes.
*
* @returns {[string | null, (key: string | null) => void]} Tuple of [apiKey, setApiKey]
*/
export function useApiKey(): [string | null, (key: string | null) => void] {
const [apiKey, setApiKeyState] = useState<string | null>(null);
// Initialize from localStorage on mount
useEffect(() => {
const readFromStorage = () => {
if (typeof window !== "undefined") {
const stored = localStorage.getItem(STORAGE_KEY);
setApiKeyState(stored);
}
};
readFromStorage();
// Listen for storage events (cross-tab updates)
const handleStorageChange = (e: StorageEvent) => {
if (e.key === STORAGE_KEY) {
setApiKeyState(e.newValue);
}
};
// Listen for custom events (same-tab updates)
const handleCustomStorageChange = () => {
readFromStorage();
};
window.addEventListener("storage", handleStorageChange);
window.addEventListener(STORAGE_EVENT, handleCustomStorageChange);
return () => {
window.removeEventListener("storage", handleStorageChange);
window.removeEventListener(STORAGE_EVENT, handleCustomStorageChange);
};
}, []);
// Setter function that updates both localStorage and state, and dispatches event
const setApiKey = useCallback((key: string | null) => {
if (typeof window !== "undefined") {
if (key === null) {
localStorage.removeItem(STORAGE_KEY);
} else {
localStorage.setItem(STORAGE_KEY, key);
}
setApiKeyState(key);
// Dispatch custom event for same-tab reactivity
window.dispatchEvent(new CustomEvent(STORAGE_EVENT));
}
}, []);
const [apiKey, setApiKey] = useLocalStorageState<string | null>("together_api_key", { defaultValue: null });
return [apiKey, setApiKey];
}
+1
View File
@@ -67,6 +67,7 @@
"tailwind-merge": "^3.3.1",
"tailwindcss-animate": "^1.0.7",
"together-ai": "^0.33.0",
"use-local-storage-state": "^19.5.0",
"vaul": "^1.1.2",
"zod": "4.2.1"
},
+15
View File
@@ -182,6 +182,9 @@ importers:
together-ai:
specifier: ^0.33.0
version: 0.33.0
use-local-storage-state:
specifier: ^19.5.0
version: 19.5.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
vaul:
specifier: ^1.1.2
version: 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
@@ -2856,6 +2859,13 @@ packages:
'@types/react':
optional: true
use-local-storage-state@19.5.0:
resolution: {integrity: sha512-sUJAyFvsmqMpBhdwaRr7GTKkkoxb6PWeNVvpBDrLuwQF1PpbJRKIbOYeLLeqJI7B3wdfFlLLCBbmOdopiSTBOw==}
engines: {node: '>=14'}
peerDependencies:
react: '>=18'
react-dom: '>=18'
use-sidecar@1.1.3:
resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
engines: {node: '>=10'}
@@ -5936,6 +5946,11 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.7
use-local-storage-state@19.5.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
dependencies:
react: 19.2.0
react-dom: 19.2.0(react@19.2.0)
use-sidecar@1.1.3(@types/react@19.2.7)(react@19.2.0):
dependencies:
detect-node-es: 1.1.0