Compare commits

...

2 Commits

Author SHA1 Message Date
jjspace b6b83e3cfd
Merge d8a7e22f04 into 41a0f18ba9 2025-11-25 13:05:18 -05:00
jjspace d8a7e22f04
wait for code to load 2025-11-25 12:27:17 -05:00
5 changed files with 52 additions and 10 deletions

View File

@ -5,9 +5,9 @@ import {
RefObject,
useCallback,
useContext,
useDeferredValue,
useEffect,
useImperativeHandle,
useMemo,
useReducer,
useRef,
useState,
@ -29,7 +29,7 @@ import {
} from "./Gallery/GalleryItemStore.ts";
import Gallery from "./Gallery/Gallery.js";
import Bucket from "./Bucket.tsx";
import { Bucket, BucketPlaceholder } from "./Bucket.tsx";
import SandcastleEditor from "./SandcastleEditor.tsx";
import {
add,
@ -51,6 +51,7 @@ import { LeftPanel, SettingsContext } from "./SettingsContext.ts";
import { MetadataPopover } from "./MetadataPopover.tsx";
import { SharePopover } from "./SharePopover.tsx";
import { SandcastlePopover } from "./SandcastlePopover.tsx";
import { urlSpecifiesSandcastle } from "./Gallery/loadFromUrl.ts";
const defaultJsCode = `import * as Cesium from "cesium";
@ -199,7 +200,7 @@ function App() {
const consoleCollapsedHeight = 33;
const [consoleExpanded, setConsoleExpanded] = useState(false);
const isStartingWithCode = !!(window.location.search || window.location.hash);
const isStartingWithCode = useMemo(() => urlSpecifiesSandcastle(), []);
const startOnEditor =
isStartingWithCode || settings.defaultPanel === "editor";
const [leftPanel, setLeftPanel] = useState<LeftPanel>(
@ -385,7 +386,6 @@ function App() {
const [initialized, setInitialized] = useState(false);
const [isLoadPending, startLoadPending] = useTransition();
const deferredIsLoading = useDeferredValue(isLoadPending);
const { useLoadFromUrl } = galleryItemStore;
const loadFromUrl = useLoadFromUrl();
useEffect(() => {
@ -607,9 +607,16 @@ function App() {
dispatch({ type: "setHtml", html: value })
}
onRun={() => runSandcastle()}
js={codeState.code}
html={codeState.html}
js={
!initialized || isLoadPending ? "// Loading..." : codeState.code
}
html={
!initialized || isLoadPending
? "<!-- Loading... -->"
: codeState.html
}
setJs={(newCode) => dispatch({ type: "setCode", code: newCode })}
readOnly={!initialized}
/>
)}
<StoreContext value={galleryItemStore}>
@ -628,7 +635,9 @@ function App() {
setConsoleExpanded={setConsoleExpanded}
>
<Allotment.Pane minSize={200}>
{!deferredIsLoading && (
{!initialized || isLoadPending ? (
<BucketPlaceholder />
) : (
<Bucket
code={codeState.committedCode}
html={codeState.committedHtml}

View File

@ -19,5 +19,12 @@
border: none;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
font-weight: bold;
font-size: 1.5rem;
font-family: sans-serif;
color: #eee;
}
}

View File

@ -11,7 +11,7 @@ type SandcastleMessage =
| { type: "consoleError"; error: string; lineNumber?: number; url?: string }
| { type: "highlight"; highlight: number };
function Bucket({
export function Bucket({
code,
html,
runNumber,
@ -218,4 +218,10 @@ function Bucket({
);
}
export default Bucket;
export function BucketPlaceholder() {
return (
<div className="bucket-container">
<div className="fullFrame">Loading...</div>
</div>
);
}

View File

@ -37,6 +37,23 @@ const fromItem = async ({ getHtmlCode, getJsCode, title }: GalleryItem) => {
}
};
/**
* Check whether the current page's url indicates a specific sandcastle.
* This is required in case other search params are included in the url that
* don't point to a sandcastle like those needed for oauth
*/
export function urlSpecifiesSandcastle() {
console.log("check url", window.location);
const searchParams = new URLSearchParams(window.location.search);
return (
searchParams.has("id") ||
(searchParams.has("code") && !searchParams.has("state")) ||
window.location.hash.indexOf("#c") === 0 ||
searchParams.has("src") ||
searchParams.has("gist")
);
}
export function loadFromUrl(
items: GalleryItem[],
legacyIds: Record<string, string>,
@ -46,7 +63,7 @@ export function loadFromUrl(
const codeParam = searchParams.get("code");
if (codeParam) {
// This is a legacy support type url that was used by ion.
// Ideally we use the #c= param as that results in shorter urls
// Ideally we use the #c= param as that results in slightly shorter urls
// The code query parameter is a Base64 encoded JSON string with `code` and `html` properties.
const json = JSON.parse(window.atob(codeParam.replaceAll(" ", "+")));

View File

@ -64,6 +64,7 @@ function SandcastleEditor({
onHtmlChange,
onRun: onRunSandcastle,
setJs,
readOnly,
}: {
ref?: RefObject<SandcastleEditorRef | null>;
darkTheme: boolean;
@ -73,6 +74,7 @@ function SandcastleEditor({
onHtmlChange: OnChange;
onRun: () => void;
setJs: (newCode: string) => void;
readOnly: boolean;
}) {
const [activeTab, setActiveTab] = useState<"js" | "html">("js");
const internalEditorRef = useRef<monaco.editor.IStandaloneCodeEditor>(null);
@ -379,6 +381,7 @@ Sandcastle.addToolbarMenu(${variableName});`);
availableFonts[fontFamily]?.cssValue ?? "Droid Sans Mono",
fontSize: fontSize,
fontLigatures: fontLigatures,
readOnly: readOnly,
}}
path={activeTab === "js" ? "script.js" : "index.html"}
language={activeTab === "js" ? "javascript" : "html"}