refactor: improve password input layout and enhance chat thread title update logic

This commit is contained in:
Anish Sarkar 2026-04-14 21:13:01 +05:30
parent f01ddf3f0a
commit 1714922830
3 changed files with 42 additions and 29 deletions

View file

@ -174,31 +174,31 @@ export function LocalLoginForm() {
<label htmlFor="password" className="block text-sm font-medium text-foreground"> <label htmlFor="password" className="block text-sm font-medium text-foreground">
{t("password")} {t("password")}
</label> </label>
<div className="relative"> <div className="relative mt-1">
<input <input
id="password" id="password"
type={showPassword ? "text" : "password"} type={showPassword ? "text" : "password"}
autoComplete="current-password" autoComplete="current-password"
required required
placeholder="Enter your password" placeholder="Enter your password"
value={password} value={password}
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
className={`mt-1 block w-full rounded-md border pr-10 px-3 py-1.5 md:py-2 shadow-sm focus:outline-none focus:ring-1 bg-background text-foreground transition-all ${ className={`block w-full rounded-md border pr-10 px-3 py-1.5 md:py-2 shadow-sm focus:outline-none focus:ring-1 bg-background text-foreground transition-all ${
error.title error.title
? "border-destructive focus:border-destructive focus:ring-destructive/40" ? "border-destructive focus:border-destructive focus:ring-destructive/40"
: "border-border focus:border-primary focus:ring-primary/40" : "border-border focus:border-primary focus:ring-primary/40"
}`} }`}
disabled={isLoggingIn} disabled={isLoggingIn}
/> />
<button <button
type="button" type="button"
onClick={() => setShowPassword((prev) => !prev)} onClick={() => setShowPassword((prev) => !prev)}
className="absolute inset-y-0 right-0 flex items-center pr-3 mt-1 text-muted-foreground hover:text-foreground" className="absolute inset-y-0 right-0 flex items-center pr-3 text-muted-foreground hover:text-foreground"
aria-label={showPassword ? t("hide_password") : t("show_password")} aria-label={showPassword ? t("hide_password") : t("show_password")}
> >
{showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />} {showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
</button> </button>
</div> </div>
</div> </div>
<button <button

View file

@ -67,6 +67,8 @@ import {
getRegenerateUrl, getRegenerateUrl,
getThreadFull, getThreadFull,
getThreadMessages, getThreadMessages,
type ThreadListItem,
type ThreadListResponse,
type ThreadRecord, type ThreadRecord,
} from "@/lib/chat/thread-persistence"; } from "@/lib/chat/thread-persistence";
import { NotFoundError } from "@/lib/error"; import { NotFoundError } from "@/lib/error";
@ -770,9 +772,21 @@ export default function NewChatPage() {
if (titleData?.title && titleData?.threadId === currentThreadId) { if (titleData?.title && titleData?.threadId === currentThreadId) {
setCurrentThread((prev) => (prev ? { ...prev, title: titleData.title } : prev)); setCurrentThread((prev) => (prev ? { ...prev, title: titleData.title } : prev));
updateChatTabTitle({ chatId: currentThreadId, title: titleData.title }); updateChatTabTitle({ chatId: currentThreadId, title: titleData.title });
queryClient.invalidateQueries({ queryClient.setQueriesData<ThreadListResponse>(
queryKey: ["threads", String(searchSpaceId)], { queryKey: ["threads", String(searchSpaceId)] },
}); (old) => {
if (!old) return old;
const updateTitle = (list: ThreadListItem[]) =>
list.map((t) =>
t.id === titleData.threadId ? { ...t, title: titleData.title } : t
);
return {
...old,
threads: updateTitle(old.threads),
archived_threads: updateTitle(old.archived_threads),
};
}
);
} }
break; break;
} }

View file

@ -27,7 +27,6 @@ export function useTypewriter(text: string, speed = 35, skipFor = "New Chat"): s
} }
let i = 0; let i = 0;
setDisplayed("");
intervalRef.current = setInterval(() => { intervalRef.current = setInterval(() => {
i++; i++;
setDisplayed(text.slice(0, i)); setDisplayed(text.slice(0, i));