Skip to content

Commit

Permalink
feat(web): add ability to display infobox in plugin playground (#1351)
Browse files Browse the repository at this point in the history
  • Loading branch information
mulengawilfred authored Jan 16, 2025
1 parent ea80389 commit 1e41e1c
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 84 deletions.
100 changes: 38 additions & 62 deletions web/src/beta/features/PluginPlayground/Code/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ type ReearthYML = {
}[];
};

type CustomInfoboxBlock = {
id: string;
name: string;
description: string;
__REEARTH_SOURCECODE: string;
extensionId: string;
pluginId: string;
};

type Props = {
files: FileType[];
};
Expand All @@ -50,72 +59,13 @@ const getYmlJson = (file: FileType) => {
};

export default ({ files }: Props) => {
const [infoboxBlocks, setInfoboxBlocks] = useState<CustomInfoboxBlock[]>();
const [widgets, setWidgets] = useState<Widgets>();
const [, setNotification] = useNotification();
const [fileOutputs, setFileOutputs] = useState<
{
title: string;
output: string;
}[]
>();

const executeCode = useCallback(() => {
const ymlFile = files.find((file) => file.title.endsWith(".yml"));

const jsFiles = files.filter((file) => file.title.endsWith(".js"));

const outputs = jsFiles.map((file) => {
try {
const fn = new Function(
`"use strict";
const reearth = {
ui: {
show: function () {}
},
popup: {
show: function () {}
},
modal: {
show: function () {}
}
};
let capturedConsole = [];
console.log = (message) => {
capturedConsole.push(message);
};
console.error = (message) => {
capturedConsole.push(message);
};
${file.sourceCode};
return capturedConsole.join("\\n");
`
);

return {
title: file.title,
output: fn()
};
} catch (error) {
if (error instanceof Error) {
return {
title: file.title,
output: error.message
};
}
return {
title: file.title,
output: "Failed to execute"
};
}
});

setFileOutputs(outputs);

if (!ymlFile) return;

const getYmlResult = getYmlJson(ymlFile);
Expand Down Expand Up @@ -182,11 +132,37 @@ export default ({ files }: Props) => {
}
);
setWidgets(widgets);

const infoboBlockFromExtension = ymlJson.extensions.reduce<
CustomInfoboxBlock[]
>((prv, cur) => {
if (cur.type !== "infoboxBlock") return prv;

const file = files.find((file) => file.title === `${cur.id}.js`);

if (!file) {
return prv;
}

return [
...prv,
{
id: cur.id,
name: cur.name,
description: cur.description,
__REEARTH_SOURCECODE: file.sourceCode,
extensionId: cur.id,
pluginId: cur.id
}
];
}, []);

setInfoboxBlocks(infoboBlockFromExtension);
}, [files, setNotification]);

return {
executeCode,
widgets,
fileOutputs
infoboxBlocks,
widgets
};
};
7 changes: 3 additions & 4 deletions web/src/beta/features/PluginPlayground/LayerList/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,17 @@ import { Layer } from "@reearth/core";
export const DEFAULT_LAYERS_PLUGIN_PLAYGROUND: Layer[] = [
{
type: "simple",
id: "01jff2ww37r9msq4an8mvxh409",
id: "1",
title: "chiyoda 3D tiles",
visible: true,
data: {
type: "3dtiles",
url: "https://assets.cms.plateau.reearth.io/assets/11/6d05db-ed47-4f88-b565-9eb385b1ebb0/13100_tokyo23-ku_2022_3dtiles%20_1_1_op_bldg_13101_chiyoda-ku_lod1/tileset.json"
},
"3dtiles": {}
}
},
{
type: "simple",
id: "01jff3fxh13h2trxstqfx363nx",
id: "2",
title: "japan-heritage",
visible: true,
data: {
Expand Down
8 changes: 5 additions & 3 deletions web/src/beta/features/PluginPlayground/LayerList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { Layer, MapRef } from "@reearth/core";
import { styled } from "@reearth/services/theme";
import { FC, MutableRefObject, useCallback, useState } from "react";
import { FC, MutableRefObject, useCallback } from "react";

import LayerItem from "./LayerItem";

type Props = {
handleLayerVisibilityUpdate: (layerId: string, visible: boolean) => void;
layers: Layer[];
selectedLayerId: string;
setSelectedLayerId: (layerId: string) => void;
visualizerRef: MutableRefObject<MapRef | null>;
};

const LayerList: FC<Props> = ({
handleLayerVisibilityUpdate,
layers,
selectedLayerId,
setSelectedLayerId,
visualizerRef
}) => {
const handleFlyTo = useCallback(
Expand All @@ -22,8 +26,6 @@ const LayerList: FC<Props> = ({
[visualizerRef]
);

const [selectedLayerId, setSelectedLayerId] = useState("");

return (
<Wrapper>
{layers &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ extensions:
zone: outer
section: left
area: top
- id: demo-infobox-block-1
type: infoboxBlock
name: Demo Infobox Block 1
- id: demo-infobox-block-2
type: infoboxBlock
name: Demo Infobox Block 2
`,
disableEdit: true,
disableDelete: true
Expand All @@ -33,8 +39,30 @@ const widgetFile: FileType = {
\`); `
};

const demoInfoboxBlock1File: FileType = {
id: "custom-my-plugin-demo-infobox-block-1",
title: "demo-infobox-block-1.js",
sourceCode: `reearth.ui.show(\`
${PRESET_PLUGIN_COMMON_STYLE}
<div id="wrapper">
<h2 style="text-align: center;">Infobox Block 1</h2>
</div>
\`); `
};

const demoInfoboxBlock2File: FileType = {
id: "custom-my-plugin-demo-infobox-block-2",
title: "demo-infobox-block-2.js",
sourceCode: `reearth.ui.show(\`
${PRESET_PLUGIN_COMMON_STYLE}
<div id="wrapper">
<h2 style="text-align: center;">Infobox Block 2</h2>
</div>
\`); `
};

export const myPlugin: PluginType = {
id: "my-plugin",
title: "My Plugin",
files: [widgetFile, yamlFile]
files: [widgetFile, demoInfoboxBlock1File, demoInfoboxBlock2File, yamlFile]
};
49 changes: 49 additions & 0 deletions web/src/beta/features/PluginPlayground/SettingsList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { CheckBox, Typography } from "@reearth/beta/lib/reearth-ui";
import { styled } from "@reearth/services/theme";
import { FC } from "react";

type Props = {
infoboxEnabled: boolean;
setInfoboxEnabled: (infoBoxEnabled: boolean) => void;
};
const SettingsList: FC<Props> = ({ infoboxEnabled, setInfoboxEnabled }) => {
return (
<Wrapper>
<Row>
<CheckBox
value={infoboxEnabled}
onChange={() => setInfoboxEnabled(!infoboxEnabled)}
/>
<Typography size="body" otherProperties={{ paddingLeft: 4 }}>
Enable Infobox
</Typography>
</Row>
{/* <Row>
<CheckBox />
<Typography size="body" otherProperties={{ paddingLeft: 4 }}>
Enable Story Panel
</Typography>
</Row> */}
</Wrapper>
);
};

const Wrapper = styled.div(({ theme }) => ({
display: "flex",
flexDirection: "column",
overflow: "auto",
padding: theme.spacing.smallest
}));

const Row = styled.div(({ theme }) => ({
display: "flex",
alignItems: "center",
padding: theme.spacing.smallest,
"&:hover": {
backgroundColor: theme.bg[1]
},
borderRadius: theme.radius.small,
minHeight: 28
}));

export default SettingsList;
61 changes: 49 additions & 12 deletions web/src/beta/features/PluginPlayground/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { TabItem } from "@reearth/beta/lib/reearth-ui";
import { Layer, MapRef } from "@reearth/core";
import { MapRef } from "@reearth/core";
import { FC, useMemo, useRef, useState } from "react";

import Code from "./Code";
Expand All @@ -8,6 +8,7 @@ import LayerList from "./LayerList";
import { DEFAULT_LAYERS_PLUGIN_PLAYGROUND } from "./LayerList/constants";
import Plugins from "./Plugins";
import usePlugins from "./Plugins/usePlugins";
import SettingsList from "./SettingsList";
import Viewer from "./Viewer";

export default () => {
Expand All @@ -29,19 +30,45 @@ export default () => {
sharedPlugin
} = usePlugins();

const { widgets, executeCode } = useCode({
const { infoboxBlocks, widgets, executeCode } = useCode({
files: selectedPlugin.files
});

const [layers, setLayers] = useState<Layer[]>(
DEFAULT_LAYERS_PLUGIN_PLAYGROUND
const [selectedLayerId, setSelectedLayerId] = useState("");
const [visibleLayerIds, setVisibleLayerIds] = useState<string[]>(
DEFAULT_LAYERS_PLUGIN_PLAYGROUND.map((l) => l.id)
);
const [infoboxEnabled, setInfoboxEnabled] = useState(true);

const handleLayerVisibilityUpdate = (layerId: string, visible: boolean) => {
setLayers((prev) =>
prev.map((layer) =>
layer.id === layerId ? { ...layer, visible } : layer
)
const layers = useMemo(() => {
return DEFAULT_LAYERS_PLUGIN_PLAYGROUND.map((layer) => {
return {
...layer,
...(infoboxEnabled
? {
infobox: {
id: layer.id,
blocks: infoboxBlocks,
property: {
default: {
enabled: {
value: true
}
}
}
}
}
: {}),
visible: visibleLayerIds.includes(layer.id)
};
});
}, [infoboxEnabled, visibleLayerIds, infoboxBlocks]);

const handleLayerVisibilityUpdate = (layerId: string) => {
setVisibleLayerIds((prev) =>
prev.includes(layerId)
? prev.filter((id) => id !== layerId)
: [...prev, layerId]
);
};

Expand All @@ -68,6 +95,8 @@ export default () => {
<LayerList
handleLayerVisibilityUpdate={handleLayerVisibilityUpdate}
layers={layers}
selectedLayerId={selectedLayerId}
setSelectedLayerId={setSelectedLayerId}
visualizerRef={visualizerRef}
/>
);
Expand Down Expand Up @@ -134,10 +163,18 @@ export default () => {
[selectedFile, executeCode, updateFileSourceCode]
);

const SettingsPanel: FC = () => (
<SettingsList
infoboxEnabled={infoboxEnabled}
setInfoboxEnabled={setInfoboxEnabled}
/>
);

return {
MainAreaTabs,
LayersPanel,
SubRightAreaTabs,
RightAreaTabs
MainAreaTabs,
RightAreaTabs,
SettingsPanel,
SubRightAreaTabs
};
};
Loading

0 comments on commit 1e41e1c

Please sign in to comment.