Skip to content

Commit fcc5ad1

Browse files
committed
UI: Allow editing of title (#246)
- make <h1> title contentEditable - title setting persists across reloads in localStorage
1 parent 305e5a0 commit fcc5ad1

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

ui/src/App.tsx

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { useEffect, useCallback } from "react";
12
import { BrowserRouter as Router, Routes, Route, Navigate, NavLink } from "react-router-dom";
23
import { useTheme } from "./contexts/ThemeProvider";
34
import { APIProvider } from "./contexts/APIProvider";
@@ -6,17 +7,52 @@ import ModelPage from "./pages/Models";
67
import ActivityPage from "./pages/Activity";
78
import ConnectionStatus from "./components/ConnectionStatus";
89
import { RiSunFill, RiMoonFill } from "react-icons/ri";
10+
import { usePersistentState } from "./hooks/usePersistentState";
911

1012
function App() {
1113
const { isNarrow, toggleTheme, isDarkMode } = useTheme();
14+
const [appTitle, setAppTitle] = usePersistentState("app-title", "llama-swap");
15+
16+
const handleTitleChange = useCallback(
17+
(newTitle: string) => {
18+
setAppTitle(newTitle);
19+
document.title = newTitle;
20+
},
21+
[setAppTitle]
22+
);
23+
24+
useEffect(() => {
25+
document.title = appTitle; // Set initial title
26+
}, [appTitle]);
1227

1328
return (
1429
<Router basename="/ui/">
1530
<APIProvider>
1631
<div className="flex flex-col h-screen">
1732
<nav className="bg-surface border-b border-border p-2 h-[75px]">
1833
<div className="flex items-center justify-between mx-auto px-4 h-full">
19-
{!isNarrow && <h1 className="flex items-center p-0">llama-swap</h1>}
34+
{!isNarrow && (
35+
<h1
36+
contentEditable
37+
suppressContentEditableWarning
38+
className="flex items-center p-0 outline-none hover:bg-gray-100 dark:hover:bg-gray-700 rounded px-1"
39+
onBlur={(e) =>
40+
handleTitleChange(e.currentTarget.textContent?.replace(/\n/g, "").trim() || "llama-swap")
41+
}
42+
onKeyDown={(e) => {
43+
if (e.key === "Enter") {
44+
e.preventDefault();
45+
const sanitizedText =
46+
e.currentTarget.textContent?.replace(/\n/g, "").trim().substring(0, 25) || "llama-swap";
47+
handleTitleChange(sanitizedText);
48+
e.currentTarget.textContent = sanitizedText;
49+
e.currentTarget.blur();
50+
}
51+
}}
52+
>
53+
{appTitle}
54+
</h1>
55+
)}
2056
<div className="flex items-center space-x-4">
2157
<NavLink to="/" className={({ isActive }) => (isActive ? "navlink active" : "navlink")}>
2258
Logs

0 commit comments

Comments
 (0)