diff --git a/api/package.json b/api/package.json index 1f899f28..19cb9002 100644 --- a/api/package.json +++ b/api/package.json @@ -46,6 +46,7 @@ "@types/bcryptjs": "^2.4.2", "@types/express": "^4.17.14", "@types/jsonwebtoken": "^8.5.9", + "@types/lodash": "^4.14.200", "@types/node": "^18.11.2", "@types/ws": "^8.5.3", "ts-jest": "^29.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c28d5824..84e201a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -111,6 +111,9 @@ importers: '@types/jsonwebtoken': specifier: ^8.5.9 version: 8.5.9 + '@types/lodash': + specifier: ^4.14.200 + version: 4.14.200 '@types/node': specifier: ^18.11.2 version: 18.11.2 @@ -366,6 +369,9 @@ importers: lib0: specifier: ^0.2.83 version: 0.2.83 + lodash: + specifier: ^4.17.21 + version: 4.17.21 monaco-editor: specifier: ^0.34.1 version: 0.34.1 @@ -445,6 +451,9 @@ importers: specifier: ^4.4.1 version: 4.4.1(@types/react@18.2.15)(immer@10.0.2)(react@18.2.0) devDependencies: + '@types/lodash': + specifier: ^4.14.200 + version: 4.14.200 '@types/node': specifier: ^20.5.6 version: 20.5.9 @@ -4486,6 +4495,10 @@ packages: '@types/node': 20.8.10 dev: true + /@types/lodash@4.14.200: + resolution: {integrity: sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q==} + dev: true + /@types/long@4.0.2: resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} dev: false diff --git a/ui/package.json b/ui/package.json index d2ccdee9..b832576a 100644 --- a/ui/package.json +++ b/ui/package.json @@ -40,6 +40,7 @@ "katex": "0.13.0", "kbar": "^0.1.0-beta.40", "lib0": "^0.2.83", + "lodash": "^4.17.21", "monaco-editor": "^0.34.1", "nanoid": "^3.0.0", "nanoid-dictionary": "^4.3.0", @@ -68,6 +69,7 @@ "zustand": "^4.4.1" }, "devDependencies": { + "@types/lodash": "^4.14.200", "@types/node": "^20.5.6", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", diff --git a/ui/src/lib/store/repoSlice.ts b/ui/src/lib/store/repoSlice.ts index ef107706..1a433bb1 100644 --- a/ui/src/lib/store/repoSlice.ts +++ b/ui/src/lib/store/repoSlice.ts @@ -5,8 +5,6 @@ import { MyState } from "."; export interface RepoSlice { repoName: string | null; - repoNameSyncing: boolean; - repoNameDirty: boolean; repoId: string | null; editMode: "view" | "edit"; setEditMode: (mode: "view" | "edit") => void; @@ -36,8 +34,6 @@ export const createRepoSlice: StateCreator = ( ) => ({ repoId: null, repoName: null, - repoNameSyncing: false, - repoNameDirty: false, collaborators: [], isPublic: false, shareOpen: false, @@ -56,7 +52,6 @@ export const createRepoSlice: StateCreator = ( set( produce((state: MyState) => { state.repoName = name; - state.repoNameDirty = true; }) ); }, diff --git a/ui/src/pages/repo.tsx b/ui/src/pages/repo.tsx index 4965197e..80b1a3d6 100644 --- a/ui/src/pages/repo.tsx +++ b/ui/src/pages/repo.tsx @@ -18,6 +18,7 @@ import { useContext, memo, createContext, + useCallback, } from "react"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; @@ -25,6 +26,8 @@ import { httpBatchLink } from "@trpc/client"; import { useStore } from "zustand"; +import debounce from "lodash/debounce"; + import { createRepoStore, RepoContext } from "../lib/store"; import { Canvas } from "../components/Canvas"; @@ -49,14 +52,26 @@ import { useAuth } from "../lib/auth"; const HeaderItem = memo(() => { const store = useContext(RepoContext)!; const repoName = useStore(store, (state) => state.repoName); - const repoNameDirty = useStore(store, (state) => state.repoNameDirty); const setRepoName = useStore(store, (state) => state.setRepoName); const editMode = useStore(store, (state) => state.editMode); + const repoId = useStore(store, (state) => state.repoId)!; - // TODO put reponame into yjs - usePrompt( - "Repo name not saved. Do you want to leave this page?", - repoNameDirty + const utils = trpc.useUtils(); + const updateRepo = trpc.repo.updateRepo.useMutation({ + onSuccess: () => { + utils.repo.getDashboardRepos.invalidate(); + }, + }); + const debouncedUpdateRepo = useCallback( + debounce( + (name: string) => { + console.log("update repo", name); + updateRepo.mutate({ id: repoId, name }); + }, + 1000, + { maxWait: 5000 } + ), + [] ); const [focus, setFocus] = useState(false); @@ -107,6 +122,7 @@ const HeaderItem = memo(() => { onChange={(e) => { const name = e.target.value; setRepoName(name); + debouncedUpdateRepo(name); }} /> ); @@ -134,7 +150,6 @@ const HeaderItem = memo(() => { ) : ( textfield )} - {repoNameDirty && saving..} ); });