Skip to content

Commit

Permalink
feat(web): add sample layers to plugin playground (#1330)
Browse files Browse the repository at this point in the history
Co-authored-by: airslice <[email protected]>
  • Loading branch information
mulengawilfred and airslice authored Jan 8, 2025
1 parent 42e2b7b commit ee4c98a
Show file tree
Hide file tree
Showing 8 changed files with 716 additions and 72 deletions.
35 changes: 0 additions & 35 deletions web/src/beta/features/PluginPlayground/Console/index.tsx

This file was deleted.

73 changes: 73 additions & 0 deletions web/src/beta/features/PluginPlayground/LayerList/LayerItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { IconButton } from "@reearth/beta/lib/reearth-ui";
import { EntryItem, EntryItemAction } from "@reearth/beta/ui/components";
import { Layer } from "@reearth/core";
import { FC, useCallback, useMemo } from "react";

interface LayerItemProps {
handleLayerVisibilityUpdate: (layerId: string, visible: boolean) => void;
layer: Layer;
onFlyTo: (layerId: string, options: { duration: number }) => void;
selectedLayerId: string;
setSelectedLayerId: (layerId: string) => void;
}

const LayerItem: FC<LayerItemProps> = ({
handleLayerVisibilityUpdate,
layer,
onFlyTo,
selectedLayerId,
setSelectedLayerId
}) => {
const handleZoomToLayer = useCallback(() => {
onFlyTo?.(layer.id, { duration: 0 });
}, [onFlyTo, layer]);

const handleToggleLayerVisibility = useCallback(() => {
handleLayerVisibilityUpdate(layer.id, !layer.visible);
}, [layer.id, layer.visible, handleLayerVisibilityUpdate]);

const handleLayerItemClick = () => {
setSelectedLayerId(layer.id);
};

const hoverActions: EntryItemAction[] | undefined = useMemo(
() => [
{
comp: layer.visible && (
<IconButton
key="zoom"
icon="crosshair"
size="small"
appearance="simple"
onClick={handleZoomToLayer}
/>
)
},
{
comp: (
<IconButton
key="visible"
icon={layer.visible ? "eye" : "eyeSlash"}
size="small"
appearance="simple"
onClick={handleToggleLayerVisibility}
/>
),
keepVisible: !layer.visible
}
],
[layer.visible, handleZoomToLayer, handleToggleLayerVisibility]
);

return (
<EntryItem
title={layer.title}
icon="file"
onClick={handleLayerItemClick}
highlighted={layer.id === selectedLayerId}
actions={hoverActions}
/>
);
};

export default LayerItem;
522 changes: 522 additions & 0 deletions web/src/beta/features/PluginPlayground/LayerList/constants.ts

Large diffs are not rendered by default.

51 changes: 51 additions & 0 deletions web/src/beta/features/PluginPlayground/LayerList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Layer, MapRef } from "@reearth/core";
import { styled } from "@reearth/services/theme";
import { FC, MutableRefObject, useCallback, useState } from "react";

import LayerItem from "./LayerItem";

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

const LayerList: FC<Props> = ({
handleLayerVisibilityUpdate,
layers,
visualizerRef
}) => {
const handleFlyTo = useCallback(
(layerId: string, options: { duration: number }) => {
visualizerRef.current?.engine.flyTo?.(layerId, options);
},
[visualizerRef]
);

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

return (
<Wrapper>
{layers &&
layers.map((l) => (
<LayerItem
handleLayerVisibilityUpdate={handleLayerVisibilityUpdate}
key={l.id}
layer={l}
onFlyTo={handleFlyTo}
selectedLayerId={selectedLayerId}
setSelectedLayerId={setSelectedLayerId}
/>
))}
</Wrapper>
);
};

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

export default LayerList;
32 changes: 23 additions & 9 deletions web/src/beta/features/PluginPlayground/Viewer/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
import { Camera } from "@reearth/beta/utils/value";
import { MapRef, ViewerProperty } from "@reearth/core";
import { config } from "@reearth/services/config";
import { useEffect, useMemo, useRef, useState } from "react";
import {
MutableRefObject,
useCallback,
useEffect,
useMemo,
useState
} from "react";

export default () => {
// Refrence: hooks of Editor/Visualizer/hooks.ts and Publish/hooks.ts
const visualizerRef = useRef<MapRef | null>(null);
export default ({
visualizerRef
}: {
visualizerRef: MutableRefObject<MapRef | null>;
}) => {
const [ready, setReady] = useState(false);
const [currentCamera, setCurrentCamera] = useState<Camera | undefined>(
undefined
);

const handleIsVisualizerUpdate = useCallback(
(value: boolean) => setReady(value),
[setReady]
);

const engineMeta = useMemo(
() => ({
cesiumIonAccessToken: config()?.cesiumIonAccessToken
Expand All @@ -35,11 +48,12 @@ export default () => {
}, []);

return {
visualizerRef,
viewerProperty,
ready,
engineMeta,
currentCamera,
setCurrentCamera
engineMeta,
handleIsVisualizerUpdate,
ready,
setCurrentCamera,
viewerProperty,
visualizerRef
};
};
18 changes: 8 additions & 10 deletions web/src/beta/features/PluginPlayground/Viewer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
import Visualizer from "@reearth/beta/features/Visualizer";
import { ComponentProps, FC } from "react";
import { Layer, MapRef } from "@reearth/core";
import { ComponentProps, FC, MutableRefObject } from "react";

import useHooks from "./hooks";

type Props = {
layers: Layer[];
widgets: ComponentProps<typeof Visualizer>["widgets"];
visualizerRef: MutableRefObject<MapRef | null>;
};

const Viewer: FC<Props> = ({ widgets }) => {
const {
visualizerRef,
viewerProperty,
ready,
engineMeta,
currentCamera,
setCurrentCamera
} = useHooks();
const Viewer: FC<Props> = ({ layers, widgets, visualizerRef }) => {
const { currentCamera, engineMeta, ready, setCurrentCamera, viewerProperty } =
useHooks({ visualizerRef });

return (
<Visualizer
engine="cesium"
visualizerRef={visualizerRef}
viewerProperty={viewerProperty}
ready={ready}
layers={layers}
engineMeta={engineMeta}
currentCamera={currentCamera}
onCameraChange={setCurrentCamera}
Expand Down
49 changes: 34 additions & 15 deletions web/src/beta/features/PluginPlayground/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { TabItem } from "@reearth/beta/lib/reearth-ui";
import { useMemo } from "react";
import { Layer, MapRef } from "@reearth/core";
import { FC, useMemo, useRef, useState } from "react";

import Code from "./Code";
import useCode from "./Code/hook";
import Console from "./Console";
import LayerList from "./LayerList";
import { DEFAULT_LAYERS_PLUGIN_PLAYGROUND } from "./LayerList/constants";
import Plugins from "./Plugins";
import usePlugins from "./Plugins/usePlugins";
import Viewer from "./Viewer";

export default () => {
const visualizerRef = useRef<MapRef | null>(null);

const {
presetPlugins,
selectPlugin,
Expand All @@ -25,32 +29,47 @@ export default () => {
sharedPlugin
} = usePlugins();

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

const [layers, setLayers] = useState<Layer[]>(
DEFAULT_LAYERS_PLUGIN_PLAYGROUND
);

const handleLayerVisibilityUpdate = (layerId: string, visible: boolean) => {
setLayers((prev) =>
prev.map((layer) =>
layer.id === layerId ? { ...layer, visible } : layer
)
);
};

// Note: currently we put visualizer in tab content, so better not have more tabs in this area,
// otherwise visualizer will got unmount and mount when switching tabs.
const MainAreaTabs: TabItem[] = useMemo(
() => [
{
id: "viewer",
name: "Viewer",
children: <Viewer widgets={widgets} />
children: (
<Viewer
layers={layers}
widgets={widgets}
visualizerRef={visualizerRef}
/>
)
}
],
[widgets]
[layers, widgets]
);

const BottomAreaTabs: TabItem[] = useMemo(
() => [
{
id: "console",
name: "Console",
children: <Console fileOutputs={fileOutputs} />
}
],
[fileOutputs]
const LayersPanel: FC = () => (
<LayerList
handleLayerVisibilityUpdate={handleLayerVisibilityUpdate}
layers={layers}
visualizerRef={visualizerRef}
/>
);

const SubRightAreaTabs: TabItem[] = useMemo(
Expand Down Expand Up @@ -117,7 +136,7 @@ export default () => {

return {
MainAreaTabs,
BottomAreaTabs,
LayersPanel,
SubRightAreaTabs,
RightAreaTabs
};
Expand Down
8 changes: 5 additions & 3 deletions web/src/beta/features/PluginPlayground/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Tabs } from "@reearth/beta/lib/reearth-ui";
import { Area, Window } from "@reearth/beta/ui/layout";
import { Area, Panel, Window } from "@reearth/beta/ui/layout";
import { FC } from "react";

import useHooks from "./hooks";

const PluginPlayground: FC = () => {
const { MainAreaTabs, BottomAreaTabs, SubRightAreaTabs, RightAreaTabs } =
const { MainAreaTabs, LayersPanel, SubRightAreaTabs, RightAreaTabs } =
useHooks();

return (
Expand All @@ -20,7 +20,9 @@ const PluginPlayground: FC = () => {
initialHeight={100}
storageId="plugin-playground-bottom-area"
>
<Tabs position="top" tabs={BottomAreaTabs} />
<Panel noPadding alwaysOpen extend title="Layers">
<LayersPanel />
</Panel>
</Area>
</Area>
<Area
Expand Down

0 comments on commit ee4c98a

Please sign in to comment.