import { Root } from "@stratakit/foundations";
import { Allotment, AllotmentHandle } from "allotment";
import "allotment/dist/style.css";
import {
ReactElement,
RefObject,
useEffect,
useImperativeHandle,
useRef,
useState,
} from "react";
import Bucket from "./Bucket";
import { Button } from "@stratakit/bricks";
import "./TestApp.css";
import classNames from "classnames";
import { GalleryItem } from "./Gallery";
import SandcastleEditor, { SandcastleEditorRef } from "./SandcastleEditor";
import { useLocalStorage } from "./util/useLocalStorage";
const defaultJsCode = `//import * as Cesium from "cesium";
//const viewer = new Cesium.Viewer("cesiumContainer");
console.log("Sandcastle loaded");
document.body.style.background = \`
no-repeat center/30% url(../images/cesium-logomark.svg),
linear-gradient(to bottom, lightskyblue, lightgreen)\`;
`;
const defaultHtmlCode = `
Loading...
`;
const GALLERY_BASE = __GALLERY_BASE_URL__;
type RightSideRef = {
toggleExpanded: () => void;
};
function RightSideAllotment({
ref,
children,
consoleCollapsedHeight,
consoleExpanded,
setConsoleExpanded,
}: {
ref: RefObject;
children: ReactElement[];
consoleCollapsedHeight: number;
consoleExpanded: boolean;
setConsoleExpanded: (expanded: boolean) => void;
}) {
const rightSideRef = useRef(null);
const rightSideSizes = useRef([0, 0]);
useImperativeHandle(ref, () => {
return {
toggleExpanded: () => toggleExpanded(),
};
});
const [previousConsoleHeight, setPreviousConsoleHeight] = useState<
number | undefined
>(undefined);
function toggleExpanded() {
console.log(rightSideRef?.current);
const [top, bottom] = rightSideSizes.current;
const totalHeight = top + bottom;
console.log("current sizes", rightSideSizes.current, totalHeight);
if (!consoleExpanded) {
const targetHeight = previousConsoleHeight ?? 200;
rightSideRef.current?.resize([totalHeight - targetHeight, targetHeight]);
} else {
setPreviousConsoleHeight(bottom);
rightSideRef.current?.resize([
totalHeight - consoleCollapsedHeight,
consoleCollapsedHeight,
]);
}
setConsoleExpanded(!consoleExpanded);
}
return (
{
if (previousConsoleHeight) {
// Unset this because we just dragged
setPreviousConsoleHeight(undefined);
}
console.log("change", sizes);
rightSideSizes.current = sizes;
}}
onDragEnd={(sizes) => {
const [, consoleSize] = sizes;
if (consoleSize <= consoleCollapsedHeight && consoleExpanded) {
setConsoleExpanded(false);
} else if (consoleSize > consoleCollapsedHeight && !consoleExpanded) {
setConsoleExpanded(true);
}
}}
onReset={() => {
const [top, bottom] = rightSideSizes.current;
const totalHeight = top + bottom;
rightSideRef.current?.resize([
totalHeight - consoleCollapsedHeight,
consoleCollapsedHeight,
]);
setConsoleExpanded(false);
}}
>
{children}
);
}
function Gallery({ loadDemo }: { loadDemo: (item: GalleryItem) => void }) {
const [galleryItems, setGalleryItems] = useState([]);
const [galleryLoaded, setGalleryLoaded] = useState(false);
useEffect(() => {
let ignore = false;
async function fetchGallery() {
const req = await fetch(`${GALLERY_BASE}/list.json`);
const resp = await req.json();
if (!ignore) {
setGalleryItems(resp.entries);
setGalleryLoaded(true);
}
}
fetchGallery();
return () => {
ignore = true;
};
}, []);
return (
{!galleryLoaded ? (
⟳
) : (
galleryItems.map((demo) => (
))
)}
);
}
function ConsoleMirror({
logs,
expanded: consoleExpanded,
toggleExpanded,
}: {
logs: string[];
expanded: boolean;
toggleExpanded: () => void;
}) {
return (
{logs.map((log, i) => (
{i + 1}: {log}
))}
);
}
export default function TestApp() {
const [theme, setTheme] = useLocalStorage<"dark" | "light">(
"sandcastle/theme",
"dark",
);
useEffect(() => {
// This should be managed by Stratakit ideally
// https://github.com/iTwin/design-system/issues/827
// document.documentElement.dataset.colorScheme = theme;
}, [theme]);
const editorRef = useRef(null);
const rightSideRef = useRef(null);
const consoleCollapsedHeight = 26;
const [consoleExpanded, setConsoleExpanded] = useState(false);
const codeState = {
committedCode: defaultJsCode,
committedHtml: defaultHtmlCode,
runNumber: 0,
};
const [jsCode, setJsCode] = useState(defaultJsCode);
function highlightLine(lineNumber: number) {
console.log("highlight line", lineNumber);
}
const [leftPanel, setLeftPanel] = useState<"editor" | "gallery">("gallery");
return (
New Sandcastle
Cesium 1.131
{leftPanel === "editor" && (
<>
{/* */}
setJsCode(value)}
onHtmlChange={(value: string = "") =>
console.log("change html", value)
}
onRun={() => console.log("run")}
js={jsCode}
html={defaultHtmlCode}
/>
>
)}
{leftPanel === "gallery" && (
{
console.log("load demo", item);
setJsCode(`// ${item.title}\n// ${item.description}`);
setLeftPanel("editor");
}}
/>
)}
{}}
code={codeState.committedCode}
html={codeState.committedHtml}
runNumber={codeState.runNumber}
highlightLine={(lineNumber) => highlightLine(lineNumber)}
>
rightSideRef.current?.toggleExpanded()}
/>
);
}