Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: collisions between examples, projects and projects examples #31

Merged
merged 1 commit into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/components/Config/ConfigDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import ConfigInput from "./ConfigInput";

const ConfigDialog = () => {
const {
getProjectMode,
getKAPLAYConfig,
updateKAPLAYConfig,
syncKAPLAYFile,
getProject,
} = useProject();
const {
update,
Expand Down Expand Up @@ -81,7 +81,7 @@ const ConfigDialog = () => {
<h2 className="text-xl">KAPLAY Configuration</h2>
</header>
<main>
{getProjectMode() === "project"
{getProject().mode === "pj"
? (
<>
<ConfigGroup title="screen & perf">
Expand Down
87 changes: 28 additions & 59 deletions src/components/Editor/MonacoEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,53 @@ import type { editor } from "monaco-editor";
import { type FC } from "react";
import { useEditor } from "../../hooks/useEditor";
import { useProject } from "../../hooks/useProject";
import { decompressCode } from "../../util/compressCode";
import { debug } from "../../util/logs";
import { configMonaco } from "./monacoConfig";

type Props = {
onMount?: () => void;
};

const IMPORT_CODE_ALERT =
"Are you sure you want to open this example? This will permanently replace your current project. You can export your current project to save it.";

const MonacoEditor: FC<Props> = (props) => {
const { updateFile, replaceProject, addFile, getFile } = useProject();
const {
setEditor,
run,
update,
currentFile,
setMonaco,
updateImageDecorations,
setGylphDecorations,
getCurrentFile,
} = useEditor();
const { updateFile, getFile } = useProject();
const { run, update, updateImageDecorations, getRuntime } = useEditor();

const handleEditorBeforeMount = (monaco: Monaco) => {
configMonaco(monaco);

const codeUrl = new URL(window.location.href).searchParams.get("code");
if (!codeUrl) return;

if (confirm(IMPORT_CODE_ALERT)) {
replaceProject({
files: new Map(),
assets: new Map(),
kaplayConfig: {},
version: "2.0.0",
mode: "example",
});

const code = decompressCode(codeUrl);

addFile({
name: "main.js",
value: code,
kind: "main",
language: "javascript",
path: "main.js",
});
}
};

const handleEditorMount = (
editor: editor.IStandaloneCodeEditor,
monaco: Monaco,
) => {
setEditor(editor);
setMonaco(monaco);
getRuntime().editor = editor;
getRuntime().monaco = monaco;
const currentFile = getRuntime().currentFile;

props.onMount?.();
editor.setValue(getFile(currentFile)?.value ?? "");

editor.onDidChangeModelContent((ev) => {
if (ev.isFlush) {
// set value

updateImageDecorations();
} else {
const currentProjectFile = getFile(getRuntime().currentFile);
if (!currentProjectFile) {
return debug(0, "Current file not found");
}

debug(
0,
"Due to text editor change, updating file",
currentProjectFile.path,
);

updateFile(currentProjectFile.path, editor.getValue());
}
});

// Editor Shortcuts
editor.addAction({
id: "run-game",
Expand All @@ -88,32 +75,16 @@ const MonacoEditor: FC<Props> = (props) => {
});

let decorations = editor.createDecorationsCollection([]);
setGylphDecorations(decorations);
getRuntime().gylphDecorations = decorations;

run();
};

const handleEditorChange = (value: string | undefined) => {
const currentProjectFile = getFile(getCurrentFile());
if (!currentProjectFile) return debug(0, "Current file not found");

debug(
0,
"Due to editor change, updating file",
currentProjectFile.path,
);

updateFile(currentProjectFile.path, value ?? "");
updateImageDecorations();
};

return (
<Editor
defaultLanguage="javascript"
defaultValue={getFile(currentFile)?.value}
beforeMount={handleEditorBeforeMount}
onMount={handleEditorMount}
onChange={handleEditorChange}
theme="kaplayrk"
language="javascript"
options={{
Expand All @@ -126,6 +97,4 @@ const MonacoEditor: FC<Props> = (props) => {
);
};

MonacoEditor.displayName = "MonacoEditor";

export default MonacoEditor;
7 changes: 5 additions & 2 deletions src/components/ExamplesBrowser/ExampleEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { assets } from "@kaplayjs/crew";
import type { FC } from "react";
import type { Example } from "../../data/examples";
import { useEditor } from "../../hooks/useEditor";
import { useProject } from "../../hooks/useProject";
import { cn } from "../../util/cn";

type Props = {
Expand All @@ -17,7 +18,8 @@ const imagesPerDifficulty: Record<string, string> = {
};

export const ExampleEntry: FC<Props> = ({ example, isProject }) => {
const { loadExample } = useEditor();
const { loadDefaultExample } = useProject();
const { loadProject } = useEditor();

const handleClick = () => {
const dialog = document.querySelector<HTMLDialogElement>(
Expand All @@ -27,8 +29,9 @@ export const ExampleEntry: FC<Props> = ({ example, isProject }) => {
dialog?.close();

if (isProject) {
loadProject(example.name);
} else {
loadExample(example.index);
loadDefaultExample(example.index);
}
};

Expand Down
15 changes: 9 additions & 6 deletions src/components/ExamplesBrowser/ExamplesBrowser.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as Tabs from "@radix-ui/react-tabs";
import { examples } from "../../data/examples";
import { examples, type Tag } from "../../data/examples";
import { ExampleEntry } from "./ExampleEntry";
import "./ExamplesBrowser.css";
import { assets } from "@kaplayjs/crew";
Expand Down Expand Up @@ -37,7 +37,7 @@ export const ExamplesBrowser = () => {
/>
</header>

<Tabs.Root className="overflow-auto">
<Tabs.Root className="overflow-auto" defaultValue="Projects">
<TabsList>
<TabTrigger
label="Projects"
Expand All @@ -57,13 +57,16 @@ export const ExamplesBrowser = () => {
<ExampleEntry
example={{
description: null,
formatedName: project.replace(
"pj-",
"",
),
formatedName: project.slice(3),
name: project,
index: "0",
tags: [
...project.startsWith("pj-")
? ["project"] as Tag[]
: ["example"] as Tag[],
],
}}
isProject
key={project}
/>
))}
Expand Down
4 changes: 2 additions & 2 deletions src/components/FileTree/FileTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import FileFolder from "./FileFolder";

const FileTree = () => {
const {
getProjectMode,
getFile,
getFilesByFolder,
getProject,
} = useProject();

return (
<div className="flex flex-col p-2 gap-2">
{getProjectMode() === "project" && (
{getProject().mode === "pj" && (
<>
<FileFolder level={1} title="Scenes">
{getFilesByFolder("scenes").length === 0
Expand Down
7 changes: 1 addition & 6 deletions src/components/Playground/GameView.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { type FC } from "react";
import { useEditor } from "../../hooks/useEditor";

type GameViewProps = {
onLoad?: () => void;
};

const GameView: FC<GameViewProps> = ({ onLoad }) => {
const {
setIframe,
} = useEditor();

return (
<iframe
ref={setIframe}
id="game-view"
tabIndex={0}
onLoad={onLoad}
style={{
Expand Down
9 changes: 4 additions & 5 deletions src/components/Playground/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import GameView from "./GameView";
const Playground = () => {
const {
project,
getProjectMode,
getProject,
createNewProject,
} = useProject();
const [loadingProject, setLoadingProject] = useState<boolean>(true);
Expand All @@ -32,7 +32,7 @@ const Playground = () => {
useEffect(() => {
if (project.files.size > 0) setLoadingProject(false);
else {
createNewProject();
createNewProject("pj");
}
}, [project]);

Expand All @@ -57,7 +57,7 @@ const Playground = () => {
<Allotment.Pane
snap
minSize={200}
visible={getProjectMode() === "project"}
visible={getProject().mode === "pj"}
>
<FileTree />
</Allotment.Pane>
Expand All @@ -70,8 +70,7 @@ const Playground = () => {
</Allotment.Pane>
<Allotment.Pane
snap
visible={getProjectMode()
=== "project"}
visible={getProject().mode === "pj"}
>
<Assets />
</Allotment.Pane>
Expand Down
24 changes: 17 additions & 7 deletions src/components/Toolbar/ExampleList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import { useEditor } from "../../hooks/useEditor";
import { useProject } from "../../hooks/useProject";

const ExampleList: FC = () => {
const { getSavedProjects } = useProject();
const { loadExample, loadProject } = useEditor();
const { getSavedProjects, loadDefaultExample } = useProject();
const { loadProject } = useEditor();

const handleExampleChange = (ev: ChangeEvent<HTMLSelectElement>) => {
const exampleIndex = ev.target.selectedOptions[0].getAttribute(
"data-example",
"data-def-example",
);

if (exampleIndex) {
loadExample(exampleIndex);
loadDefaultExample(exampleIndex);
} else {
loadProject(ev.target.value);
}
Expand All @@ -30,16 +30,26 @@ const ExampleList: FC = () => {
Projects
</option>

{getSavedProjects().map((project) => (
<option key={project} value={project} data-project>
{getSavedProjects("pj").map((project) => (
<option key={project} value={project}>
{project.replace("pj-", "")}
</option>
))}

<option className="text-md" disabled value="none">
User Examples
</option>

{getSavedProjects("ex").map((project) => (
<option key={project} value={project}>
{project.replace("ex-", "")}
</option>
))}

<option className="text-md" disabled>KAPLAY Examples</option>

{examples.map((example) => (
<option key={example.name} data-example={example.index}>
<option key={example.name} data-def-example={example.index}>
{example.name}
</option>
))}
Expand Down
26 changes: 12 additions & 14 deletions src/components/Toolbar/ProjectStatus.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,33 @@ import { assets } from "@kaplayjs/crew";
import { useProject } from "../../hooks/useProject";

const ProjectStatus = () => {
const {
getProjectMode,
project,
saveProject,
getProjectName,
setProjectName,
isProjectSaved,
} = useProject();
const { saveProject, getProject, setProject, projectIsSaved } =
useProject();

const handleSaveProject = () => {
saveProject(getProjectName());
saveProject(getProject().name);
};

const handleEditName = () => {
const projectName = prompt("Project name");
const projectName = prompt("New project name?");
if (!projectName) return;

setProjectName(projectName);
setProject({ name: projectName });
};

if (getProject().isDefault) return;

return (
<div className="flex flex-row gap-2">
<div className="uppercase | badge badge-lg badge-primary">
{getProjectMode() === "project" ? "PJ" : "EX"}
{getProject().mode}
</div>

<div>
{project.name || "Untitled Project"}
{!isProjectSaved(getProjectName()) && <span>*</span>}
{getProject().name}
{!projectIsSaved(getProject().name, getProject().mode) && (
<span>*</span>
)}
</div>

<button
Expand Down
Loading