Skip to content
This repository has been archived by the owner on Apr 25, 2023. It is now read-only.

Commit

Permalink
feat: Add scene property overriding to Re:Earth API (#224)
Browse files Browse the repository at this point in the history
* UI of tile map opacity slider, fix WAS bug

* add opacity to visualizer

* small refactor of SliderField

* remove console log

* updates based on PR review

* add scene property overriding to reearth api

* fix merge

* fixed merge for all property fields

* fix storybook error

* wip: override scene from plugin

* Fix storybook ci error

* Fix mutation issue in merge, move mergeProperty to utils

* Move mergeProperty into Visualizer

* Update src/components/molecules/Visualizer/utils.ts

Co-authored-by: rot1024 <aayhrot@gmail.com>

Co-authored-by: rot1024 <aayhrot@gmail.com>
  • Loading branch information
KaWaite and rot1024 committed May 23, 2022
1 parent 7a11b30 commit b076033
Show file tree
Hide file tree
Showing 15 changed files with 90 additions and 39 deletions.
14 changes: 0 additions & 14 deletions src/components/molecules/Visualizer/Engine/Cesium/useEngineRef.ts
Expand Up @@ -3,15 +3,12 @@ import { Math as CesiumMath } from "cesium";
import { useImperativeHandle, Ref, RefObject, useMemo, useRef } from "react";
import type { CesiumComponentRef } from "resium";

import { delayedObject, merge } from "@reearth/util/object";

import type { Ref as EngineRef } from "..";

import builtinPrimitives from "./builtin";
import Cluster from "./Cluster";
import { getLocationFromScreenXY, flyTo, lookAt, getCamera } from "./common";

const exposed = delayedObject(Cesium);
const exposedFunctions = Object.values(Cesium).filter(
(e): e is (...args: any[]) => any => typeof e === "function",
);
Expand All @@ -26,19 +23,8 @@ export default function useEngineRef(
): EngineRef {
const cancelCameraFlight = useRef<() => void>();
const e = useMemo((): EngineRef => {
const api = merge(exposed, {
get viewer(): Cesium.Viewer | undefined {
return cesium.current?.cesiumElement;
},
});

return {
name: "cesium",
pluginApi: {
get Cesium() {
return api;
},
},
isMarshalable,
requestRender: () => {
const viewer = cesium.current?.cesiumElement;
Expand Down
12 changes: 11 additions & 1 deletion src/components/molecules/Visualizer/Plugin/api.ts
Expand Up @@ -14,7 +14,10 @@ import type {
Tag,
} from "./types";

export type CommonReearth = Omit<Reearth, "plugin" | "ui" | "block" | "layer" | "widget">;
export type CommonReearth = Omit<
Reearth,
"visualizer" | "plugin" | "ui" | "block" | "layer" | "widget"
> & { visualizer: Omit<Reearth["visualizer"], "overrideProperty"> };

export function exposed({
render,
Expand All @@ -26,6 +29,7 @@ export function exposed({
layer,
block,
widget,
overrideSceneProperty,
}: {
render: (
html: string,
Expand All @@ -44,6 +48,7 @@ export function exposed({
layer?: () => Layer | undefined;
block?: () => Block | undefined;
widget?: () => Widget | undefined;
overrideSceneProperty?: (pluginId: string, property: any) => void;
}): GlobalThis {
return merge({
console: {
Expand All @@ -53,6 +58,11 @@ export function exposed({
reearth: merge(
commonReearth,
{
visualizer: {
overrideProperty: (property: any) => {
overrideSceneProperty?.(plugin ? `${plugin.id}/${plugin.extensionId}` : "", property);
},
},
ui: {
show: (
html: string,
Expand Down
6 changes: 3 additions & 3 deletions src/components/molecules/Visualizer/Plugin/context.tsx
Expand Up @@ -36,7 +36,7 @@ export type EngineContext = {
export type Props = {
engine: EngineContext;
engineName: string;
sceneProperty?: any;
mergedSceneProperty?: any;
tags?: Tag[];
camera?: CameraPosition;
layers: LayerStore;
Expand Down Expand Up @@ -73,7 +73,7 @@ declare global {
export function Provider({
engine: { api, isMarshalable, builtinPrimitives },
engineName,
sceneProperty,
mergedSceneProperty,
tags,
camera,
layers,
Expand All @@ -100,7 +100,7 @@ export function Provider({
);

const getLayers = useGet(layers);
const getSceneProperty = useGet(sceneProperty);
const getSceneProperty = useGet(mergedSceneProperty);
const getTags = useGet(tags ?? []);
const getCamera = useGet(camera);
const getSelectedLayer = useGet(selectedLayer);
Expand Down
7 changes: 7 additions & 0 deletions src/components/molecules/Visualizer/Plugin/hooks.ts
Expand Up @@ -20,6 +20,7 @@ export default function ({
pluginProperty,
onRender,
onResize,
overrideSceneProperty,
}: {
pluginId?: string;
extensionId?: string;
Expand All @@ -29,6 +30,7 @@ export default function ({
widget?: Widget;
block?: Block;
pluginProperty?: any;
overrideSceneProperty?: (pluginId: string, property: any) => void;
onRender?: (
options:
| {
Expand All @@ -53,6 +55,7 @@ export default function ({
layer,
widget,
pluginProperty,
overrideSceneProperty,
onRender,
onResize,
}) ?? [];
Expand Down Expand Up @@ -89,6 +92,7 @@ export function useAPI({
layer,
block,
widget,
overrideSceneProperty,
onRender,
onResize,
}: {
Expand All @@ -99,6 +103,7 @@ export function useAPI({
layer: Layer | undefined;
block: Block | undefined;
widget: Widget | undefined;
overrideSceneProperty?: (pluginId: string, property: any) => void;
onRender?: (
options:
| {
Expand Down Expand Up @@ -192,6 +197,7 @@ export function useAPI({
resize(width, height);
onResize?.(width, height, extended);
},
overrideSceneProperty,
});
};
}, [
Expand All @@ -205,6 +211,7 @@ export function useAPI({
getWidget,
onRender,
onResize,
overrideSceneProperty,
]);

useEffect(() => {
Expand Down
3 changes: 3 additions & 0 deletions src/components/molecules/Visualizer/Plugin/index.tsx
Expand Up @@ -32,6 +32,7 @@ export type Props = {
layer?: Layer;
widget?: Widget;
block?: Block;
overrideSceneProperty?: (pluginId: string, property: any) => void;
onClick?: () => void;
onRender?: (
options:
Expand Down Expand Up @@ -63,6 +64,7 @@ export default function Plugin({
widget,
block,
pluginProperty,
overrideSceneProperty,
onClick,
onRender,
onResize,
Expand All @@ -76,6 +78,7 @@ export default function Plugin({
widget,
block,
pluginProperty,
overrideSceneProperty,
onRender,
onResize,
});
Expand Down
1 change: 1 addition & 0 deletions src/components/molecules/Visualizer/Plugin/types.ts
Expand Up @@ -220,6 +220,7 @@ export type Visualizer = {
readonly camera: Camera;
/** Current scene property */
readonly property?: any;
readonly overrideProperty: (property: any) => void;
};

type Rect = {
Expand Down
11 changes: 1 addition & 10 deletions src/components/molecules/Visualizer/Primitive/index.tsx
@@ -1,8 +1,8 @@
import { mergeWith } from "lodash";
import React, { ComponentType, useMemo } from "react";

import { useContext } from "../Plugin";
import type { Layer } from "../Plugin";
import { mergeProperty } from "../utils";

export type { Layer } from "../Plugin";

Expand Down Expand Up @@ -53,12 +53,3 @@ export default function PrimitiveComponent<P = any, PP = any, SP = any>({
<Builtin {...props} layer={actualLayer} />
) : null;
}

export function mergeProperty(a: any, b: any) {
return mergeWith(
{ ...a },
b,
(s: any, v: any, _k: string | number | symbol, _obj: any, _src: any, stack: { size: number }) =>
stack.size > 0 || Array.isArray(v) ? v ?? s : undefined,
);
}
3 changes: 3 additions & 0 deletions src/components/molecules/Visualizer/Widget/index.tsx
Expand Up @@ -23,6 +23,7 @@ export type Props<PP = any, SP = any> = {
pluginBaseUrl?: string;
layout?: WidgetLayout;
editing?: boolean;
overrideSceneProperty?: (pluginId: string, property: any) => void;
onExtend?: (id: string, extended: boolean | undefined) => void;
};

Expand All @@ -38,6 +39,7 @@ export default function WidgetComponent<PP = any, SP = any>({
pluginBaseUrl,
layout,
onExtend,
overrideSceneProperty,
...props
}: Props<PP, SP>) {
const { align, location } = layout ?? {};
Expand Down Expand Up @@ -96,6 +98,7 @@ export default function WidgetComponent<PP = any, SP = any>({
widget={w}
onRender={handleRender}
onResize={handleResize}
overrideSceneProperty={overrideSceneProperty}
/>
);
}
Expand Down
Expand Up @@ -20,6 +20,7 @@ type Props = {
sceneProperty?: any;
pluginProperty?: { [key: string]: any };
pluginBaseUrl?: string;
overrideSceneProperty?: (pluginId: string, property: any) => void;
// note that layoutConstraint will be always undefined in published pages
layoutConstraint?: { [w in string]: WidgetLayoutConstraint };
};
Expand All @@ -31,6 +32,7 @@ export default function Area({
align,
widgets,
pluginProperty,
overrideSceneProperty,
layoutConstraint,
...props
}: Props) {
Expand Down Expand Up @@ -92,6 +94,7 @@ export default function Area({
extended={extended}
editing={editing}
onExtend={handleExtend}
overrideSceneProperty={overrideSceneProperty}
{...props}
/>
)}
Expand Down
Expand Up @@ -13,6 +13,7 @@ export type Props = {
sceneProperty?: any;
pluginProperty?: { [key: string]: any };
pluginBaseUrl?: string;
overrideSceneProperty?: (pluginId: string, property: any) => void;
};

const sections = ["left", "center", "right"] as const;
Expand All @@ -27,6 +28,7 @@ export default function Zone({
pluginBaseUrl,
isEditable,
isBuilt,
overrideSceneProperty,
children,
}: PropsWithChildren<Props>) {
return (
Expand All @@ -52,6 +54,7 @@ export default function Zone({
pluginBaseUrl={pluginBaseUrl}
isEditable={isEditable}
isBuilt={isBuilt}
overrideSceneProperty={overrideSceneProperty}
/>
),
)}
Expand Down
Expand Up @@ -44,6 +44,7 @@ export type Props = {
},
) => void;
onWidgetAlignSystemUpdate?: (location: Location, align: Alignment) => void;
overrideSceneProperty?: (pluginId: string, property: any) => void;
};

const WidgetAlignSystem: React.FC<Props> = ({
Expand All @@ -57,6 +58,7 @@ const WidgetAlignSystem: React.FC<Props> = ({
layoutConstraint,
onWidgetUpdate,
onWidgetAlignSystemUpdate,
overrideSceneProperty,
}) => {
const { handleMove, handleExtend, handleAlignmentChange } = useHooks({
onWidgetUpdate,
Expand Down Expand Up @@ -90,6 +92,7 @@ const WidgetAlignSystem: React.FC<Props> = ({
pluginBaseUrl={pluginBaseUrl}
isEditable={isEditable}
isBuilt={isBuilt}
overrideSceneProperty={overrideSceneProperty}
layoutConstraint={layoutConstraint}
/>
)}
Expand All @@ -103,6 +106,7 @@ const WidgetAlignSystem: React.FC<Props> = ({
pluginBaseUrl={pluginBaseUrl}
isEditable={isEditable}
isBuilt={isBuilt}
overrideSceneProperty={overrideSceneProperty}
layoutConstraint={layoutConstraint}>
<ZoneComponent
zoneName="inner"
Expand All @@ -112,6 +116,7 @@ const WidgetAlignSystem: React.FC<Props> = ({
pluginBaseUrl={pluginBaseUrl}
isEditable={isEditable}
isBuilt={isBuilt}
overrideSceneProperty={overrideSceneProperty}
layoutConstraint={layoutConstraint}
/>
</ZoneComponent>
Expand Down
25 changes: 23 additions & 2 deletions src/components/molecules/Visualizer/hooks.ts
@@ -1,4 +1,5 @@
import { Rectangle, Cartographic, Math as CesiumMath } from "cesium";
import { omit } from "lodash";
import { useRef, useEffect, useMemo, useState, useCallback, RefObject } from "react";
import { initialize, pageview } from "react-ga";
import { useSet } from "react-use";
Expand All @@ -16,6 +17,7 @@ import type { Props as InfoboxProps, Block } from "./Infobox";
import { LayerStore, emptyLayerStore } from "./Layers";
import type { ProviderProps } from "./Plugin";
import type { CameraOptions, FlyToDestination, LookAtDestination, Tag } from "./Plugin/types";
import { mergeProperty } from "./utils";

export default ({
engineType,
Expand Down Expand Up @@ -52,6 +54,23 @@ export default ({
}) => {
const engineRef = useRef<EngineRef>(null);

const [overriddenSceneProperty, overrideSceneProperty] = useState<{ [pluginId: string]: any }>(
{},
);

const handleScenePropertyOverride = useCallback((pluginId: string, property: any) => {
overrideSceneProperty(p =>
pluginId && property ? { ...p, [pluginId]: property } : omit(p, pluginId),
);
}, []);

const mergedSceneProperty = useMemo(() => {
return Object.values(overriddenSceneProperty).reduce(
(p, v) => mergeProperty(p, v),
sceneProperty,
);
}, [sceneProperty, overriddenSceneProperty]);

const wrapperRef = useRef<HTMLDivElement>(null);
const { ref: dropRef, isDroppable } = useDrop(
useMemo(
Expand Down Expand Up @@ -141,7 +160,7 @@ export default ({
const providerProps: ProviderProps = useProviderProps(
{
engineName: engineType || "",
sceneProperty,
mergedSceneProperty,
tags,
camera: innerCamera,
selectedLayer,
Expand Down Expand Up @@ -174,17 +193,19 @@ export default ({
selectedLayer,
layerSelectionReason,
layerOverriddenProperties,
isLayerDragging,
selectedBlockId,
innerCamera,
infobox,
mergedSceneProperty,
isLayerHidden,
selectLayer,
selectBlock,
updateCamera,
isLayerDragging,
handleLayerDrag,
handleLayerDrop,
handleInfoboxMaskClick,
overrideSceneProperty: handleScenePropertyOverride,
};
};

Expand Down

0 comments on commit b076033

Please sign in to comment.