Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions apps/desktop/src/components/editor-area/note-header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { type ChangeEvent } from "react";

import { getCurrentWebviewWindowLabel } from "@hypr/plugin-windows";
import { useSession } from "@hypr/utils/contexts";
import { useTitleGenerationPendingState } from "../../../hooks/enhance-pending";
import Chips from "./chips";
import ListenButton from "./listen-button";
import TitleInput from "./title-input";
import TitleShimmer from "./title-shimmer";

interface NoteHeaderProps {
onNavigateToEditor?: () => void;
Expand All @@ -19,6 +21,7 @@ export function NoteHeader(
) {
const updateTitle = useSession(sessionId, (s) => s.updateTitle);
const sessionTitle = useSession(sessionId, (s) => s.session.title);
const isTitleGenerating = useTitleGenerationPendingState(sessionId);

const handleTitleChange = (e: ChangeEvent<HTMLInputElement>) => {
updateTitle(e.target.value);
Expand All @@ -31,12 +34,15 @@ export function NoteHeader(
return (
<div className="flex items-center w-full pl-8 pr-6 pb-4 gap-4">
<div className="flex-1 space-y-1">
<TitleInput
editable={editable}
value={sessionTitle}
onChange={handleTitleChange}
onNavigateToEditor={onNavigateToEditor}
/>
<TitleShimmer isShimmering={isTitleGenerating}>
<TitleInput
editable={editable}
value={sessionTitle}
onChange={handleTitleChange}
onNavigateToEditor={onNavigateToEditor}
isGenerating={isTitleGenerating}
/>
</TitleShimmer>
<Chips sessionId={sessionId} hashtags={hashtags} />
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ interface TitleInputProps {
onChange: (e: ChangeEvent<HTMLInputElement>) => void;
onNavigateToEditor?: () => void;
editable?: boolean;
isGenerating?: boolean;
}

export default function TitleInput({
value,
onChange,
onNavigateToEditor,
editable,
isGenerating = false,
}: TitleInputProps) {
const { t } = useLingui();

Expand All @@ -23,15 +25,22 @@ export default function TitleInput({
}
};

const getPlaceholder = () => {
if (isGenerating) {
return t`Generating title...`;
}
return t`Untitled`;
};

return (
<input
disabled={!editable}
disabled={!editable || isGenerating}
id="note-title-input"
type="text"
onChange={onChange}
value={value}
placeholder={t`Untitled`}
className="w-full border-none bg-transparent text-2xl font-bold focus:outline-none placeholder:text-neutral-400"
placeholder={getPlaceholder()}
className="w-full border-none bg-transparent text-2xl font-bold focus:outline-none placeholder:text-neutral-400 transition-opacity duration-200"
onKeyDown={handleKeyDown}
/>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { cn } from "@hypr/ui/lib/utils";
import { motion } from "motion/react";
import { useEffect, useState } from "react";

interface TitleShimmerProps {
children: React.ReactNode;
className?: string;
isShimmering?: boolean;
}

export default function TitleShimmer({ children, className, isShimmering = false }: TitleShimmerProps) {
const [key, setKey] = useState(0);

useEffect(() => {
const handleResize = () => setKey(prev => prev + 1);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);

if (!isShimmering) {
return <div className={cn("relative w-full", className)}>{children}</div>;
}

return (
<div key={key} className={cn("relative w-full overflow-hidden", className)}>
<motion.div
className="absolute inset-0 z-10 pointer-events-none"
initial={{ x: "-100%" }}
animate={{ x: "100%" }}
transition={{
repeat: Infinity,
duration: 1.2,
ease: "easeInOut",
repeatDelay: 0.5,
}}
style={{
background: "linear-gradient(90deg, transparent 0%, rgba(255,255,255,0.6) 50%, transparent 100%)",
width: "50%",
}}
/>
<div className="relative opacity-60 animate-pulse">
{children}
</div>
</div>
);
}
14 changes: 14 additions & 0 deletions apps/desktop/src/hooks/enhance-pending.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,17 @@ export function useEnhancePendingState(sessionId: string) {

return isEnhancePending;
}

export function useTitleGenerationPendingState(sessionId: string) {
const titleStates = useMutationState({
filters: { mutationKey: ["generateTitle", sessionId], exact: true },
select: (mutation) => mutation.state.status,
});

const isTitleGenerationPending = useMemo(
() => titleStates.some((s) => s === "pending"),
[titleStates],
);

return isTitleGenerationPending;
}
6 changes: 5 additions & 1 deletion apps/desktop/src/locales/en/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,10 @@ msgstr "Full name"
msgid "General"
msgstr "General"

#: src/components/editor-area/note-header/title-input.tsx:30
msgid "Generating title..."
msgstr "Generating title..."

#: src/components/welcome-modal/welcome-view.tsx:36
msgid "Get Started"
msgstr "Get Started"
Expand Down Expand Up @@ -1076,7 +1080,7 @@ msgstr "Type to search..."
msgid "Ugh! Can't use it!"
msgstr "Ugh! Can't use it!"

#: src/components/editor-area/note-header/title-input.tsx:33
#: src/components/editor-area/note-header/title-input.tsx:32
msgid "Untitled"
msgstr "Untitled"

Expand Down
6 changes: 5 additions & 1 deletion apps/desktop/src/locales/ko/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,10 @@ msgstr ""
msgid "General"
msgstr ""

#: src/components/editor-area/note-header/title-input.tsx:30
msgid "Generating title..."
msgstr ""

#: src/components/welcome-modal/welcome-view.tsx:36
msgid "Get Started"
msgstr ""
Expand Down Expand Up @@ -1076,7 +1080,7 @@ msgstr ""
msgid "Ugh! Can't use it!"
msgstr ""

#: src/components/editor-area/note-header/title-input.tsx:33
#: src/components/editor-area/note-header/title-input.tsx:32
msgid "Untitled"
msgstr ""

Expand Down
6 changes: 3 additions & 3 deletions apps/docs/data/i18n.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[
{
"language": "ko",
"total": 267,
"missing": 267
"total": 268,
"missing": 268
},
{
"language": "en (source)",
"total": 267,
"total": 268,
"missing": 0
}
]
Loading