Skip to content

Commit

Permalink
chore(web): story panel refactor (#715)
Browse files Browse the repository at this point in the history
  • Loading branch information
KaWaite committed Oct 18, 2023
1 parent bac4ba8 commit 86dbb58
Show file tree
Hide file tree
Showing 46 changed files with 777 additions and 465 deletions.
4 changes: 4 additions & 0 deletions server/pkg/builtin/manifest.yml
Expand Up @@ -1839,6 +1839,7 @@ extensions:
title: Duration
suffix: s
min: 0
defaultValue: 2
- id: cameraDelay
type: number
title: Delay
Expand Down Expand Up @@ -2033,10 +2034,12 @@ extensions:
ui: padding
min: 0
max: 100
defaultValue: { top: 20, bottom: 20, left: 20, right: 20 }
- id: gap
title: Gap
type: number
suffix: px
defaultValue: 20
- id: title
title: Title Setting
fields:
Expand All @@ -2058,6 +2061,7 @@ extensions:
title: Duration
suffix: s
min: 0
defaultValue: 2
- id: cameraDelay
type: number
title: Delay
Expand Down
4 changes: 2 additions & 2 deletions web/src/beta/components/DragAndDropList/index.tsx
Expand Up @@ -13,7 +13,7 @@ export type Props<Item extends { id: string } = { id: string }> = {
getId: (item: Item) => string;
onItemDrop(item: Item, targetIndex: number): void;
renderItem: (item: Item, index: number) => ReactNode;
gap: number;
gap?: number;
};

function DragAndDropList<Item extends { id: string } = { id: string }>({
Expand Down Expand Up @@ -98,5 +98,5 @@ export default DragAndDropList;
const SWrapper = styled.div<Pick<Props, "gap">>`
display: flex;
flex-direction: column;
${({ gap }) => `gap: ${gap}px`}
${({ gap }) => gap && `gap: ${gap}px;`}
`;
22 changes: 0 additions & 22 deletions web/src/beta/components/Overlay/index.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion web/src/beta/components/fields/SpacingInput/index.tsx
Expand Up @@ -47,9 +47,9 @@ const SpacingInput: React.FC<Props> = ({ name, description, value, min, max, onC
<StyledRectangle>
{SPACING_POSITIONS.map((position, index) => (
<SpacingField
key={position}
value={memoizedSpacingValues[index]}
suffix="px"
key={position}
position={position}
min={min}
max={max}
Expand Down
99 changes: 85 additions & 14 deletions web/src/beta/features/Editor/Visualizer/convert.ts
Expand Up @@ -14,8 +14,10 @@ import {
import { WidgetAreaPadding } from "@reearth/beta/lib/core/Crust/Widgets/WidgetAlignSystem/types";
import type { Block, Tag } from "@reearth/beta/lib/core/mantle/compat/types";
import type { Layer } from "@reearth/beta/lib/core/Map";
import { Story, StoryBlock, StoryPage } from "@reearth/beta/lib/core/StoryPanel/types";
import { valueTypeFromGQL } from "@reearth/beta/utils/value";
import { NLSLayer } from "@reearth/services/api/layersApi/utils";
import { toUi } from "@reearth/services/api/propertyApi/utils";
import {
type Maybe,
type WidgetZone as WidgetZoneType,
Expand All @@ -31,6 +33,9 @@ import {
PropertyFieldFragmentFragment,
ValueType as GQLValueType,
NlsLayerCommonFragment,
Story as GqlStory,
StoryPage as GqlStoryPage,
StoryBlock as GqlStoryBlock,
} from "@reearth/services/gql";

type P = { [key in string]: any };

Check warning on line 41 in web/src/beta/features/Editor/Visualizer/convert.ts

View workflow job for this annotation

GitHub Actions / ci-web / ci

Unexpected any. Specify a different type
Expand Down Expand Up @@ -177,6 +182,35 @@ export const convertWidgets = (
};
};

export const convertStory = (story?: GqlStory): Story | undefined => {
if (!story) return undefined;

const storyPages = (pages: GqlStoryPage[]): StoryPage[] =>
pages.map(p => ({
id: p.id,
title: p.title,
propertyId: p.propertyId,
property: processProperty(undefined, p.property),
blocks: storyBlocks(p.blocks),
}));

const storyBlocks = (blocks: GqlStoryBlock[]): StoryBlock[] =>
blocks.map(b => ({
id: b.id,
pluginId: b.pluginId,
extensionId: b.extensionId,
name: b.property?.schema?.groups.find(g => g.schemaGroupId === "default")?.title,
propertyId: b.property?.id,
property: processProperty(undefined, b.property),
}));

return {
id: story.id,
title: story.title,
pages: storyPages(story.pages),
};
};

export const processProperty = (
parent: PropertyFragmentFragment | null | undefined,
orig?: PropertyFragmentFragment | null | undefined,
Expand Down Expand Up @@ -204,11 +238,20 @@ export const processProperty = (
}),
{},
);

const mergedProperty: P = Object.fromEntries(
Object.entries(allItems)
.map(([key, value]) => {
const { schema, orig, parent } = value;
if (!orig && !parent) {
if (schema.isList) {
return [key, undefined];
}
return [
key,
processPropertyGroups(schema, undefined, undefined, linkedDatasetId, datasets),
];
}

if (
(!orig || orig.__typename === "PropertyGroupList") &&
(!parent || parent.__typename === "PropertyGroupList")
Expand Down Expand Up @@ -264,20 +307,48 @@ const processPropertyGroups = (
);

return Object.fromEntries(
Object.entries(allFields)
.map(([key, { parent, orig }]) => {
const used = orig || parent;
if (!used) return [key, null];

const datasetSchemaId = used?.links?.[0]?.datasetSchemaId;
const datasetFieldId = used?.links?.[0]?.datasetSchemaFieldId;
if (datasetSchemaId && linkedDatasetId && datasetFieldId) {
return [key, datasetValue(datasets, datasetSchemaId, linkedDatasetId, datasetFieldId)];
}
Object.entries(allFields).map(([key, { schema, parent, orig }]) => {
const used = orig || parent;

return [key, valueFromGQL(used.value, used.type)?.value];
})
.filter(([, value]) => typeof value !== "undefined" && value !== null),
const fieldMeta = {
type: valueTypeFromGQL(schema.type) || undefined,
ui: toUi(schema.ui) || undefined,
title: schema.translatedTitle || undefined,
description: schema.translatedDescription || undefined,
};

if (!used) {
return [
key,
{
...fieldMeta,
value: schema.defaultValue
? valueFromGQL(schema.defaultValue, schema.type)?.value
: undefined,
},
];
}

const datasetSchemaId = used?.links?.[0]?.datasetSchemaId;
const datasetFieldId = used?.links?.[0]?.datasetSchemaFieldId;
if (datasetSchemaId && linkedDatasetId && datasetFieldId) {
return [
key,
{
...fieldMeta,
value: datasetValue(datasets, datasetSchemaId, linkedDatasetId, datasetFieldId),
},
];
}

return [
key,
{
...fieldMeta,
value: valueFromGQL(used.value, used.type)?.value,
},
];
}),
);
};

Expand Down
12 changes: 9 additions & 3 deletions web/src/beta/features/Editor/Visualizer/hooks.ts
Expand Up @@ -25,19 +25,19 @@ import {
isVisualizerReadyVar,
} from "@reearth/services/state";

import { convertWidgets, processLayers } from "./convert";
import { convertStory, convertWidgets, processLayers } from "./convert";
import type { BlockType } from "./type";

export default ({
sceneId,
isBuilt,
storyId,
isBuilt,
currentPage,
showStoryPanel,
}: {
sceneId?: string;
isBuilt?: boolean;
storyId?: string;
isBuilt?: boolean;
currentPage?: Page;
showStoryPanel?: boolean;
}) => {
Expand Down Expand Up @@ -204,6 +204,11 @@ export default ({
[sceneId, useUpdateWidgetAlignSystem],
);

const story = useMemo(
() => convertStory(scene?.stories.find(s => s.id === storyId)),
[storyId, scene?.stories],
);

const handleStoryBlockCreate = useCallback(
async (pageId?: string, extensionId?: string, pluginId?: string, index?: number) => {
if (!extensionId || !pluginId || !storyId || !pageId) return;
Expand Down Expand Up @@ -264,6 +269,7 @@ export default ({
tags,
widgets,
layers,
story,
blocks,
isCapturing,
sceneMode,
Expand Down
3 changes: 2 additions & 1 deletion web/src/beta/features/Editor/Visualizer/index.tsx
Expand Up @@ -52,6 +52,7 @@ const Visualizer: React.FC<Props> = ({
clusters,
layers,
widgets,
story,
tags,
selectedLayerId,
blocks,
Expand Down Expand Up @@ -132,7 +133,7 @@ const Visualizer: React.FC<Props> = ({
renderInfoboxInsertionPopup={renderInfoboxInsertionPopUp}>
{showStoryPanel && (
<StoryPanel
selectedStory={selectedStory}
selectedStory={story}
currentPageId={currentPage?.id}
isAutoScrolling={isAutoScrolling}
installableBlocks={installableBlocks}
Expand Down
@@ -1,5 +1,8 @@
import ColorField from "@reearth/beta/components/fields/ColorField";
import TextInput from "@reearth/beta/components/fields/TextField";
import ToggleField from "@reearth/beta/components/fields/ToggleField";
import SidePanelSectionField from "@reearth/beta/components/SidePanelSectionField";
import { useT } from "@reearth/services/i18n";
import { WidgetAreaPadding, WidgetAreaState } from "@reearth/services/state";

type Props = {
Expand All @@ -8,11 +11,12 @@ type Props = {
};

const ContainerSettings: React.FC<Props> = ({ widgetArea, onWidgetAreaStateChange }) => {
// TODO: This is dummy UI
const t = useT();

return (
<SidePanelSectionField>
<TextInput
name="Padding Top"
name={t("Padding top")}
value={widgetArea?.padding?.top.toString()}
onChange={newVal => {
onWidgetAreaStateChange({
Expand All @@ -25,7 +29,7 @@ const ContainerSettings: React.FC<Props> = ({ widgetArea, onWidgetAreaStateChang
}}
/>
<TextInput
name="Padding Right"
name={t("Padding right")}
value={widgetArea?.padding?.right.toString()}
onChange={newVal => {
onWidgetAreaStateChange({
Expand All @@ -38,7 +42,7 @@ const ContainerSettings: React.FC<Props> = ({ widgetArea, onWidgetAreaStateChang
}}
/>
<TextInput
name="Padding Bottom"
name={t("Padding bottom")}
value={widgetArea?.padding?.bottom.toString()}
onChange={newVal => {
onWidgetAreaStateChange({
Expand All @@ -51,7 +55,7 @@ const ContainerSettings: React.FC<Props> = ({ widgetArea, onWidgetAreaStateChang
}}
/>
<TextInput
name="Padding Left"
name={t("Padding left")}
value={widgetArea?.padding?.left.toString()}
onChange={newVal => {
onWidgetAreaStateChange({
Expand All @@ -65,7 +69,7 @@ const ContainerSettings: React.FC<Props> = ({ widgetArea, onWidgetAreaStateChang
/>

<TextInput
name="Gap Spacing"
name={t("Gap spacing")}
value={(widgetArea?.gap ?? 0).toString()}
onChange={newVal => {
onWidgetAreaStateChange({
Expand All @@ -74,9 +78,26 @@ const ContainerSettings: React.FC<Props> = ({ widgetArea, onWidgetAreaStateChang
});
}}
/>

<div>[Switch field] Align Center {!!widgetArea?.centered}</div>
<div>[Color field] Background Color {widgetArea?.background}</div>
<ToggleField
name={t("Align centered")}
checked={!!widgetArea?.centered}
onChange={newVal => {
onWidgetAreaStateChange({
...widgetArea,
centered: newVal,
});
}}
/>
<ColorField
name={t("Background color")}
value={widgetArea?.background}
onChange={newVal => {
onWidgetAreaStateChange({
...widgetArea,
background: newVal,
});
}}
/>
</SidePanelSectionField>
);
};
Expand Down

0 comments on commit 86dbb58

Please sign in to comment.