diff --git a/app/src/components/editor.tsx b/app/src/components/editor.tsx index e505013..fee44c2 100644 --- a/app/src/components/editor.tsx +++ b/app/src/components/editor.tsx @@ -1,14 +1,41 @@ import "./editor.css"; +import beforeunload from "../helpers/beforeunload"; +import throttle from "../helpers/throttle"; -export default () => ( - { - e.currentTarget.setAttribute( - "rows", - String(Math.max(2, e.currentTarget.value.split("\n").length)) - ); - }} - > -); +const intervalMs = 333; + +const { block, unblock } = beforeunload(); + +const updatePage = throttle(async function (params: { + id: number; + title: string; + text: string; +}) { + const res = await fetch( + new URL(`/pages?id=eq.${params.id}`, import.meta.env.QUOT_API_URL), + { + method: "PUT", + headers: { "content-type": "application/json" }, + body: JSON.stringify(params), + } + ); + if (res.ok) unblock(); +}, +intervalMs); + +export default (props: { id: number }) => { + return ( + { + const text = e.currentTarget.value; + const lines = text.split("\n"); + block(); + updatePage({ id: props.id, title: lines[0] ?? "", text }); + e.currentTarget.setAttribute("rows", String(Math.max(2, lines.length))); + }} + > + ); +}; diff --git a/app/src/helpers/beforeunload.ts b/app/src/helpers/beforeunload.ts new file mode 100644 index 0000000..d106e02 --- /dev/null +++ b/app/src/helpers/beforeunload.ts @@ -0,0 +1,18 @@ +function beforeunload() { + function listener(e: BeforeUnloadEvent) { + e.preventDefault(); + e.returnValue = ""; + } + + function block() { + window.addEventListener("beforeunload", listener); + } + + function unblock() { + window.removeEventListener("beforeunload", listener); + } + + return { block, unblock }; +} + +export default beforeunload; diff --git a/app/src/helpers/throttle.ts b/app/src/helpers/throttle.ts new file mode 100644 index 0000000..f43afbc --- /dev/null +++ b/app/src/helpers/throttle.ts @@ -0,0 +1,21 @@ +function throttle any>( + fn: Fn, + ms: number +): (...args: Parameters) => void { + let throttledFn = () => undefined; + let throttled: boolean = false; + + return (...args: Parameters): void => { + throttledFn = () => fn(...args); + if (throttled) return; + + setTimeout(() => { + throttledFn(); + throttled = false; + }, ms); + + throttled = true; + }; +} + +export default throttle; diff --git a/app/src/pages/page.tsx b/app/src/pages/page.tsx index 5f6c3c0..17b1a81 100644 --- a/app/src/pages/page.tsx +++ b/app/src/pages/page.tsx @@ -22,7 +22,7 @@ export default (props: { id: number }) => { return ( - + {() => JSON.stringify(page(), null, " ")} );
{() => JSON.stringify(page(), null, " ")}