From 2ecc2734b3194ab1bb0cadee7a254db3be82fca8 Mon Sep 17 00:00:00 2001 From: Deokhaeng Lee Date: Sun, 10 Aug 2025 10:48:59 -0700 Subject: [PATCH 1/3] fixed template typing issue --- .../components/settings/views/template.tsx | 69 ++++++++++--------- 1 file changed, 36 insertions(+), 33 deletions(-) diff --git a/apps/desktop/src/components/settings/views/template.tsx b/apps/desktop/src/components/settings/views/template.tsx index 34c627d400..7dcbbbc979 100644 --- a/apps/desktop/src/components/settings/views/template.tsx +++ b/apps/desktop/src/components/settings/views/template.tsx @@ -13,7 +13,7 @@ import { Popover, PopoverContent, PopoverTrigger } from "@hypr/ui/components/ui/ import { Textarea } from "@hypr/ui/components/ui/textarea"; import { Trans, useLingui } from "@lingui/react/macro"; import { CopyIcon, MoreHorizontalIcon, TrashIcon } from "lucide-react"; -import { useCallback, useState } from "react"; +import { useCallback, useState, useEffect } from "react"; import { SectionsList } from "../components/template-sections"; interface TemplateEditorProps { @@ -94,36 +94,41 @@ export default function TemplateEditor({ return title.replace(/^(\p{Emoji})\s*/u, ""); }; + // Local state for both inputs + const [titleText, setTitleText] = useState(() => getTitleWithoutEmoji(template.title || "")); + const [descriptionText, setDescriptionText] = useState(template.description || ""); const [selectedEmoji, setSelectedEmoji] = useState(() => extractEmojiFromTitle(template.title || "")); - const [emojiPopoverOpen, setEmojiPopoverOpen] = useState(false); - const handleChangeTitle = useCallback( - (e: React.ChangeEvent) => { - const titleWithoutEmoji = e.target.value; - const fullTitle = selectedEmoji + " " + titleWithoutEmoji; - onTemplateUpdate({ ...template, title: fullTitle }); - }, - [onTemplateUpdate, template, selectedEmoji], - ); + // Sync local state when template ID changes (new template loaded) + useEffect(() => { + setTitleText(getTitleWithoutEmoji(template.title || "")); + setDescriptionText(template.description || ""); + setSelectedEmoji(extractEmojiFromTitle(template.title || "")); + }, [template.id]); + + // Simple handlers with local state + const handleChangeTitle = (e: React.ChangeEvent) => { + const newTitle = e.target.value; + setTitleText(newTitle); // Update local state immediately + + const fullTitle = selectedEmoji + " " + newTitle; + onTemplateUpdate({ ...template, title: fullTitle }); + }; - const handleEmojiSelect = useCallback( - (emoji: string) => { - setSelectedEmoji(emoji); - const titleWithoutEmoji = getTitleWithoutEmoji(template.title || ""); - const fullTitle = emoji + " " + titleWithoutEmoji; - onTemplateUpdate({ ...template, title: fullTitle }); - setEmojiPopoverOpen(false); - }, - [onTemplateUpdate, template], - ); + const handleEmojiSelect = (emoji: string) => { + setSelectedEmoji(emoji); + const fullTitle = emoji + " " + titleText; // Use local state + onTemplateUpdate({ ...template, title: fullTitle }); + setEmojiPopoverOpen(false); + }; - const handleChangeDescription = useCallback( - (e: React.ChangeEvent) => { - onTemplateUpdate({ ...template, description: e.target.value }); - }, - [onTemplateUpdate, template], - ); + const handleChangeDescription = (e: React.ChangeEvent) => { + const newDescription = e.target.value; + setDescriptionText(newDescription); // Update local state immediately + + onTemplateUpdate({ ...template, description: newDescription }); + }; const handleChangeSections = useCallback( (sections: Template["sections"]) => { @@ -145,7 +150,7 @@ export default function TemplateEditor({
- {/* Emoji Selector */} + {/* Emoji Selector - unchanged */}
- {/* Menu Button - Show for all templates with different options */} {isCreator && ( @@ -228,8 +231,8 @@ export default function TemplateEditor({