From b6175352d06faab8bb89ee12a2fa92a6c4566c8e Mon Sep 17 00:00:00 2001 From: benya Date: Sun, 8 Mar 2026 13:55:24 +0300 Subject: [PATCH] web: disable hardcoded tenor gifs and add configured fallback --- web/.env.example | 3 +++ web/src/components/MessageComposer.tsx | 22 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/web/.env.example b/web/.env.example index 4e4bf2d..67b3697 100644 --- a/web/.env.example +++ b/web/.env.example @@ -1,2 +1,5 @@ VITE_API_BASE_URL=http://localhost:8000/api/v1 VITE_WS_URL=ws://localhost:8000/api/v1/realtime/ws +VITE_GIF_PROVIDER= +VITE_TENOR_API_KEY= +VITE_TENOR_CLIENT_KEY=benya_messenger_web diff --git a/web/src/components/MessageComposer.tsx b/web/src/components/MessageComposer.tsx index 70e69cc..9ebdf7b 100644 --- a/web/src/components/MessageComposer.tsx +++ b/web/src/components/MessageComposer.tsx @@ -31,8 +31,10 @@ const GIF_PRESETS: Array<{ name: string; url: string }> = [ const STICKER_FAVORITES_KEY = "bm_sticker_favorites_v1"; const GIF_FAVORITES_KEY = "bm_gif_favorites_v1"; -const TENOR_API_KEY = "LIVDSRZULELA"; -const TENOR_CLIENT_KEY = "benya_messenger_web"; +const GIF_PROVIDER = (import.meta.env.VITE_GIF_PROVIDER ?? "").toLowerCase(); +const TENOR_API_KEY = (import.meta.env.VITE_TENOR_API_KEY ?? "").trim(); +const TENOR_CLIENT_KEY = (import.meta.env.VITE_TENOR_CLIENT_KEY ?? "benya_messenger_web").trim(); +const GIF_SEARCH_ENABLED = GIF_PROVIDER === "tenor" && TENOR_API_KEY.length > 0; function loadFavorites(key: string): Set { try { @@ -102,6 +104,7 @@ export function MessageComposer() { const [gifQuery, setGifQuery] = useState(""); const [gifResults, setGifResults] = useState>([]); const [gifLoading, setGifLoading] = useState(false); + const [gifSearchError, setGifSearchError] = useState(null); const [favoriteStickers, setFavoriteStickers] = useState>(() => loadFavorites(STICKER_FAVORITES_KEY)); const [favoriteGifs, setFavoriteGifs] = useState>(() => loadFavorites(GIF_FAVORITES_KEY)); const [captionDraft, setCaptionDraft] = useState(""); @@ -321,11 +324,19 @@ export function MessageComposer() { if (!showGifMenu || term.length < 2) { setGifResults([]); setGifLoading(false); + setGifSearchError(null); + return; + } + if (!GIF_SEARCH_ENABLED) { + setGifResults([]); + setGifLoading(false); + setGifSearchError("GIF search is not configured. Using preset GIFs."); return; } let cancelled = false; const timer = window.setTimeout(() => { setGifLoading(true); + setGifSearchError(null); void (async () => { try { const params = new URLSearchParams({ @@ -338,6 +349,9 @@ export function MessageComposer() { }); const response = await fetch(`https://tenor.googleapis.com/v2/search?${params.toString()}`); if (!response.ok) { + if (response.status === 400) { + throw new Error("GIF provider rejected the request. Configure your own API key."); + } throw new Error("gif search failed"); } const data = (await response.json()) as { @@ -355,6 +369,7 @@ export function MessageComposer() { } catch { if (!cancelled) { setGifResults([]); + setGifSearchError("GIF search is unavailable right now. Using preset GIFs."); } } finally { if (!cancelled) { @@ -902,7 +917,7 @@ export function MessageComposer() { ) : null} {showStickerMenu ? ( -
+

Stickers

@@ -1008,6 +1023,7 @@ export function MessageComposer() { ))}
{gifLoading ?

Searching GIF...

: null} + {gifSearchError ?

{gifSearchError}

: null}
) : null}