Skip to content

Commit

Permalink
chore(web): add story text block (#653)
Browse files Browse the repository at this point in the history
  • Loading branch information
airslice authored Sep 5, 2023
1 parent 708833b commit 6abb7b0
Show file tree
Hide file tree
Showing 106 changed files with 4,789 additions and 45 deletions.
2 changes: 2 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
"@emotion/react": "11.11.0",
"@emotion/styled": "11.11.0",
"@floating-ui/react": "0.24.7",
"@lexical/react": "0.12.0",
"@mapbox/vector-tile": "1.3.1",
"@monaco-editor/react": "4.5.1",
"@popperjs/core": "2.11.7",
Expand Down Expand Up @@ -144,6 +145,7 @@
"jsonpath-plus": "7.2.0",
"jszip": "3.10.1",
"leaflet": "1.9.3",
"lexical": "0.12.0",
"localforage": "1.10.0",
"lodash-es": "4.17.21",
"lru-cache": "8.0.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { debounce } from "lodash-es";
import { useMemo, useContext } from "react";

import RichTextEditor from "@reearth/beta/lib/lexical/RichTextEditor";

import { BlockContext } from "../common/Wrapper";

export type Props = {
text?: string;
onUpdate?: (text: string) => void;
};

const TextBlockEditor: React.FC<Props> = ({ text, onUpdate }) => {
const debouncedHandleTextUpdate = useMemo(
() => (onUpdate ? debounce(onUpdate, 1000) : undefined),
[onUpdate],
);

const context = useContext(BlockContext);

return (
<RichTextEditor
editMode={!!context?.editMode}
text={text}
onChange={debouncedHandleTextUpdate}
scrollableContainerId="story-page"
/>
);
};

export default TextBlockEditor;
Original file line number Diff line number Diff line change
@@ -1,33 +1,48 @@
import { useMemo } from "react";
import { useCallback, useMemo } from "react";

import Text from "@reearth/beta/components/Text";
import { ValueTypes } from "@reearth/beta/utils/value";

import { getFieldValue } from "../../../utils";
import { CommonProps as BlockProps } from "../../types";
import usePropertyValueUpdate from "../common/usePropertyValueUpdate";
import BlockWrapper from "../common/Wrapper";

import TextBlockEditor from "./Editor";

export type Props = BlockProps;

// Text block is very special, it will not edit values with field components
// from the common editor panel, but manage it by itself directly.

const TextBlock: React.FC<Props> = ({ block, isSelected, ...props }) => {
const text = useMemo(
() => getFieldValue(block?.property?.items ?? [], "text") as ValueTypes["string"],
[block?.property?.items],
);

const { handlePropertyValueUpdate } = usePropertyValueUpdate();

const handleTextUpdate = useCallback(
(text: string) => {
const schemaGroup = block?.property?.items?.find(
i => i.schemaGroup === "default",
)?.schemaGroup;
if (!block?.property?.id || !schemaGroup) return;
handlePropertyValueUpdate(schemaGroup, block?.property?.id, "text", "string")(text);
},
[block?.property?.id, block?.property?.items, handlePropertyValueUpdate],
);

return (
<BlockWrapper
title={block?.title}
icon={block?.extensionId}
isSelected={isSelected}
propertyId={block?.property?.id}
propertyItems={block?.property?.items}
settingsEnabled={false}
{...props}>
{text && (
<Text size="body" customColor>
{text}
</Text>
)}
<TextBlockEditor text={text} onUpdate={handleTextUpdate} />
</BlockWrapper>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode } from "react";
import { ReactNode, createContext } from "react";

import FieldComponents from "@reearth/beta/components/fields/PropertyFields";
import { stopClickPropagation } from "@reearth/beta/utils/events";
Expand All @@ -10,6 +10,8 @@ import Template from "../../Template";

import useHooks from "./hooks";

export const BlockContext = createContext<{ editMode?: boolean } | undefined>(undefined);

type Spacing = {
top: number;
bottom: number;
Expand All @@ -25,6 +27,7 @@ type Props = {
propertyId?: string;
propertyItems?: Item[];
dndEnabled?: boolean;
settingsEnabled?: boolean;
onClick?: () => void;
onClickAway?: () => void;
onRemove?: () => void;
Expand All @@ -38,6 +41,7 @@ const BlockWrapper: React.FC<Props> = ({
propertyId,
propertyItems,
dndEnabled = true,
settingsEnabled = true,
onClick,
onClickAway,
onRemove,
Expand All @@ -58,29 +62,31 @@ const BlockWrapper: React.FC<Props> = ({
});

return (
<SelectableArea
title={title}
icon={icon}
isSelected={isSelected}
propertyId={propertyId}
dndEnabled={dndEnabled}
showSettings={showSettings}
propertyItems={propertyItems}
editMode={editMode}
setEditMode={setEditMode}
onEditModeToggle={handleEditModeToggle}
onSettingsToggle={handleSettingsToggle}
onRemove={onRemove}
onClickAway={onClickAway}>
<Block padding={padding} onClick={handleBlockClick}>
{children ?? <Template icon={icon} />}
</Block>
{editMode && propertyId && defaultSettings && (
<EditorPanel onClick={stopClickPropagation}>
<FieldComponents propertyId={propertyId} item={defaultSettings} />
</EditorPanel>
)}
</SelectableArea>
<BlockContext.Provider value={{ editMode }}>
<SelectableArea
title={title}
icon={icon}
isSelected={isSelected}
propertyId={propertyId}
dndEnabled={dndEnabled}
showSettings={showSettings}
propertyItems={propertyItems}
editMode={editMode}
setEditMode={setEditMode}
onEditModeToggle={handleEditModeToggle}
onSettingsToggle={handleSettingsToggle}
onRemove={onRemove}
onClickAway={onClickAway}>
<Block padding={padding} onClick={handleBlockClick}>
{children ?? <Template icon={icon} />}
</Block>
{editMode && propertyId && defaultSettings && settingsEnabled && (
<EditorPanel onClick={stopClickPropagation}>
<FieldComponents propertyId={propertyId} item={defaultSettings} />
</EditorPanel>
)}
</SelectableArea>
</BlockContext.Provider>
);
};

Expand All @@ -99,11 +105,5 @@ const Block = styled.div<{ padding?: Spacing }>`
const EditorPanel = styled.div`
background: ${({ theme }) => theme.bg[1]};
color: ${({ theme }) => theme.content.main};
height: 100px;
padding: 12px;
z-index: 100;
position: absolute;
top: 100%;
left: -1px;
right: -1px;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ export default ({ isSelected, propertyItems, onClick }: Props) => {
const handleBlockClick = useCallback(
(e: MouseEvent<HTMLDivElement>) => {
e.stopPropagation();
if (showSettings && isSelected) return;
if ((showSettings && isSelected) || editMode) return;
onClick?.();
},
[onClick, showSettings, isSelected],
[onClick, showSettings, isSelected, editMode],
);

const defaultSettings: Item | undefined = useMemo(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useCallback } from "react";

import { ValueType, ValueTypes } from "@reearth/beta/utils/value";
import { usePropertyFetcher } from "@reearth/services/api";

// Unlick common story blocks which will use the auto generted field components editor,
// Some special story blocks will use the custom editor components and need to update date directly.
export default () => {
const { useUpdatePropertyValue } = usePropertyFetcher();

const handlePropertyValueUpdate = useCallback(
(
schemaGroupId: string,
propertyId: string,
fieldId: string,
vt: ValueType,
itemId?: string,
) => {
return async (v?: ValueTypes[ValueType]) => {
await useUpdatePropertyValue(propertyId, schemaGroupId, itemId, fieldId, "en", v, vt);
};
},
[useUpdatePropertyValue],
);

return {
handlePropertyValueUpdate,
};
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Bootstrap Icons
https://icons.getbootstrap.com

Licensed under MIT license
https://github.com/twbs/icons/blob/main/LICENSE.md
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 6abb7b0

Please sign in to comment.