Spaces:
Sleeping
Sleeping
Update src/components/App.tsx
Browse files- src/components/App.tsx +7 -47
src/components/App.tsx
CHANGED
|
@@ -9,7 +9,6 @@ import DeployButton from "./deploy-button/deploy-button";
|
|
| 9 |
import { defaultHTML } from "../utils/consts";
|
| 10 |
import Tabs from "./tabs/tabs";
|
| 11 |
import AskAI from "./ask-ai/ask-ai";
|
| 12 |
-
import { Auth } from "../utils/types";
|
| 13 |
import Preview from "./preview/preview";
|
| 14 |
import RedirectModal from "./redirect-modal/redirect-modal";
|
| 15 |
|
|
@@ -19,58 +18,34 @@ function App() {
|
|
| 19 |
const preview = useRef<HTMLDivElement>(null);
|
| 20 |
const editor = useRef<HTMLDivElement>(null);
|
| 21 |
const resizer = useRef<HTMLDivElement>(null);
|
| 22 |
-
// Removed editorRef
|
| 23 |
|
| 24 |
const [isResizing, setIsResizing] = useState(false);
|
| 25 |
const [error, setError] = useState(false);
|
| 26 |
const [html, setHtml] = useState((htmlStorage as string) ?? defaultHTML);
|
| 27 |
const [isAiWorking, setisAiWorking] = useState(false);
|
| 28 |
-
const [auth, setAuth] = useState<Auth | undefined>(undefined);
|
| 29 |
const [showRedirectModal, setShowRedirectModal] = useState(true);
|
| 30 |
|
| 31 |
-
const fetchMe = async () => {
|
| 32 |
-
const res = await fetch("/api/@me");
|
| 33 |
-
if (res.ok) {
|
| 34 |
-
const data = await res.json();
|
| 35 |
-
setAuth(data);
|
| 36 |
-
} else {
|
| 37 |
-
setAuth(undefined);
|
| 38 |
-
}
|
| 39 |
-
};
|
| 40 |
-
|
| 41 |
-
/**
|
| 42 |
-
* Resets the layout based on screen size
|
| 43 |
-
* - For desktop: Sets editor to 1/3 width and preview to 2/3
|
| 44 |
-
* - For mobile: Removes inline styles to let CSS handle it
|
| 45 |
-
*/
|
| 46 |
const resetLayout = () => {
|
| 47 |
if (!editor.current || !preview.current) return;
|
| 48 |
|
| 49 |
-
// lg breakpoint is 1024px based on useBreakpoint definition and Tailwind defaults
|
| 50 |
if (window.innerWidth >= 1024) {
|
| 51 |
-
|
| 52 |
-
const resizerWidth = resizer.current?.offsetWidth ?? 8; // w-2 = 0.5rem = 8px
|
| 53 |
const availableWidth = window.innerWidth - resizerWidth;
|
| 54 |
-
const initialEditorWidth = availableWidth / 3;
|
| 55 |
-
const initialPreviewWidth = availableWidth - initialEditorWidth;
|
| 56 |
editor.current.style.width = `${initialEditorWidth}px`;
|
| 57 |
preview.current.style.width = `${initialPreviewWidth}px`;
|
| 58 |
} else {
|
| 59 |
-
// Remove inline styles for smaller screens, let CSS flex-col handle it
|
| 60 |
editor.current.style.width = "";
|
| 61 |
preview.current.style.width = "";
|
| 62 |
}
|
| 63 |
};
|
| 64 |
|
| 65 |
-
/**
|
| 66 |
-
* Handles resizing when the user drags the resizer
|
| 67 |
-
* Ensures minimum widths are maintained for both panels
|
| 68 |
-
*/
|
| 69 |
const handleResize = (e: MouseEvent) => {
|
| 70 |
if (!editor.current || !preview.current || !resizer.current) return;
|
| 71 |
|
| 72 |
const resizerWidth = resizer.current.offsetWidth;
|
| 73 |
-
const minWidth = 100;
|
| 74 |
const maxWidth = window.innerWidth - resizerWidth - minWidth;
|
| 75 |
|
| 76 |
const editorWidth = e.clientX;
|
|
@@ -97,7 +72,6 @@ function App() {
|
|
| 97 |
document.removeEventListener("mouseup", handleMouseUp);
|
| 98 |
};
|
| 99 |
|
| 100 |
-
// Prevent accidental navigation away when AI is working or content has changed
|
| 101 |
useEvent("beforeunload", (e) => {
|
| 102 |
if (isAiWorking || html !== defaultHTML) {
|
| 103 |
e.preventDefault();
|
|
@@ -105,27 +79,19 @@ function App() {
|
|
| 105 |
}
|
| 106 |
});
|
| 107 |
|
| 108 |
-
// Initialize component on mount
|
| 109 |
useMount(() => {
|
| 110 |
-
// Fetch user data
|
| 111 |
-
fetchMe();
|
| 112 |
-
|
| 113 |
-
// Restore content from storage if available
|
| 114 |
if (htmlStorage) {
|
| 115 |
removeHtmlStorage();
|
| 116 |
toast.warn("Previous HTML content restored from local storage.");
|
| 117 |
}
|
| 118 |
|
| 119 |
-
// Set initial layout based on window size
|
| 120 |
resetLayout();
|
| 121 |
|
| 122 |
-
// Attach event listeners
|
| 123 |
if (!resizer.current) return;
|
| 124 |
resizer.current.addEventListener("mousedown", handleMouseDown);
|
| 125 |
window.addEventListener("resize", resetLayout);
|
| 126 |
});
|
| 127 |
|
| 128 |
-
// Clean up event listeners on unmount
|
| 129 |
useUnmount(() => {
|
| 130 |
document.removeEventListener("mousemove", handleResize);
|
| 131 |
document.removeEventListener("mouseup", handleMouseUp);
|
|
@@ -152,11 +118,10 @@ function App() {
|
|
| 152 |
setHtml(defaultHTML);
|
| 153 |
setError(false);
|
| 154 |
removeHtmlStorage();
|
| 155 |
-
// Removed editorRef scroll logic
|
| 156 |
}
|
| 157 |
}}
|
| 158 |
>
|
| 159 |
-
<DeployButton html={html} error={error}
|
| 160 |
</Header>
|
| 161 |
<main className="max-lg:flex-col flex w-full">
|
| 162 |
<div
|
|
@@ -191,18 +156,13 @@ function App() {
|
|
| 191 |
setHtml(newValue);
|
| 192 |
setError(false);
|
| 193 |
}}
|
| 194 |
-
// Removed onMount for editorRef
|
| 195 |
/>
|
| 196 |
<AskAI
|
| 197 |
html={html}
|
| 198 |
-
setHtml={setHtml}
|
| 199 |
-
// Removed editorRef prop
|
| 200 |
isAiWorking={isAiWorking}
|
| 201 |
setisAiWorking={setisAiWorking}
|
| 202 |
-
onScrollToBottom={() => {
|
| 203 |
-
// Consider if scrolling is still needed here, maybe based on html length change?
|
| 204 |
-
// For now, removing the direct editor scroll.
|
| 205 |
-
}}
|
| 206 |
/>
|
| 207 |
</div>
|
| 208 |
<div
|
|
|
|
| 9 |
import { defaultHTML } from "../utils/consts";
|
| 10 |
import Tabs from "./tabs/tabs";
|
| 11 |
import AskAI from "./ask-ai/ask-ai";
|
|
|
|
| 12 |
import Preview from "./preview/preview";
|
| 13 |
import RedirectModal from "./redirect-modal/redirect-modal";
|
| 14 |
|
|
|
|
| 18 |
const preview = useRef<HTMLDivElement>(null);
|
| 19 |
const editor = useRef<HTMLDivElement>(null);
|
| 20 |
const resizer = useRef<HTMLDivElement>(null);
|
|
|
|
| 21 |
|
| 22 |
const [isResizing, setIsResizing] = useState(false);
|
| 23 |
const [error, setError] = useState(false);
|
| 24 |
const [html, setHtml] = useState((htmlStorage as string) ?? defaultHTML);
|
| 25 |
const [isAiWorking, setisAiWorking] = useState(false);
|
|
|
|
| 26 |
const [showRedirectModal, setShowRedirectModal] = useState(true);
|
| 27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
const resetLayout = () => {
|
| 29 |
if (!editor.current || !preview.current) return;
|
| 30 |
|
|
|
|
| 31 |
if (window.innerWidth >= 1024) {
|
| 32 |
+
const resizerWidth = resizer.current?.offsetWidth ?? 8;
|
|
|
|
| 33 |
const availableWidth = window.innerWidth - resizerWidth;
|
| 34 |
+
const initialEditorWidth = availableWidth / 3;
|
| 35 |
+
const initialPreviewWidth = availableWidth - initialEditorWidth;
|
| 36 |
editor.current.style.width = `${initialEditorWidth}px`;
|
| 37 |
preview.current.style.width = `${initialPreviewWidth}px`;
|
| 38 |
} else {
|
|
|
|
| 39 |
editor.current.style.width = "";
|
| 40 |
preview.current.style.width = "";
|
| 41 |
}
|
| 42 |
};
|
| 43 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
const handleResize = (e: MouseEvent) => {
|
| 45 |
if (!editor.current || !preview.current || !resizer.current) return;
|
| 46 |
|
| 47 |
const resizerWidth = resizer.current.offsetWidth;
|
| 48 |
+
const minWidth = 100;
|
| 49 |
const maxWidth = window.innerWidth - resizerWidth - minWidth;
|
| 50 |
|
| 51 |
const editorWidth = e.clientX;
|
|
|
|
| 72 |
document.removeEventListener("mouseup", handleMouseUp);
|
| 73 |
};
|
| 74 |
|
|
|
|
| 75 |
useEvent("beforeunload", (e) => {
|
| 76 |
if (isAiWorking || html !== defaultHTML) {
|
| 77 |
e.preventDefault();
|
|
|
|
| 79 |
}
|
| 80 |
});
|
| 81 |
|
|
|
|
| 82 |
useMount(() => {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
if (htmlStorage) {
|
| 84 |
removeHtmlStorage();
|
| 85 |
toast.warn("Previous HTML content restored from local storage.");
|
| 86 |
}
|
| 87 |
|
|
|
|
| 88 |
resetLayout();
|
| 89 |
|
|
|
|
| 90 |
if (!resizer.current) return;
|
| 91 |
resizer.current.addEventListener("mousedown", handleMouseDown);
|
| 92 |
window.addEventListener("resize", resetLayout);
|
| 93 |
});
|
| 94 |
|
|
|
|
| 95 |
useUnmount(() => {
|
| 96 |
document.removeEventListener("mousemove", handleResize);
|
| 97 |
document.removeEventListener("mouseup", handleMouseUp);
|
|
|
|
| 118 |
setHtml(defaultHTML);
|
| 119 |
setError(false);
|
| 120 |
removeHtmlStorage();
|
|
|
|
| 121 |
}
|
| 122 |
}}
|
| 123 |
>
|
| 124 |
+
<DeployButton html={html} error={error} />
|
| 125 |
</Header>
|
| 126 |
<main className="max-lg:flex-col flex w-full">
|
| 127 |
<div
|
|
|
|
| 156 |
setHtml(newValue);
|
| 157 |
setError(false);
|
| 158 |
}}
|
|
|
|
| 159 |
/>
|
| 160 |
<AskAI
|
| 161 |
html={html}
|
| 162 |
+
setHtml={setHtml}
|
|
|
|
| 163 |
isAiWorking={isAiWorking}
|
| 164 |
setisAiWorking={setisAiWorking}
|
| 165 |
+
onScrollToBottom={() => {}}
|
|
|
|
|
|
|
|
|
|
| 166 |
/>
|
| 167 |
</div>
|
| 168 |
<div
|