Skip to content

Commit

Permalink
chore(web): double click on page name (#815)
Browse files Browse the repository at this point in the history
  • Loading branch information
mkumbobeaty authored Nov 16, 2023
1 parent f4fc804 commit ccf3c25
Show file tree
Hide file tree
Showing 7 changed files with 205 additions and 31 deletions.
17 changes: 17 additions & 0 deletions web/src/beta/features/Editor/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { devices } from "@reearth/beta/features/Editor/tabs/widgets/Nav/Devices"
import type { MapRef } from "@reearth/beta/lib/core/Map/ref";
import type { FlyTo } from "@reearth/beta/lib/core/types";
import type { Camera } from "@reearth/beta/utils/value";
import { usePropertyFetcher } from "@reearth/services/api";
import {
useWidgetAlignEditorActivated,
useIsVisualizerReady,
Expand Down Expand Up @@ -31,6 +32,7 @@ export default ({ tab }: { sceneId: string; tab: Tab }) => {
const handleDataSourceManagerCloser = useCallback(() => setShowDataSourceManager(false), []);

const handleDataSourceManagerOpener = useCallback(() => setShowDataSourceManager(true), []);
const { useUpdatePropertyValue } = usePropertyFetcher();

const [showWidgetEditor, setWidgetEditor] = useWidgetAlignEditorActivated();

Expand Down Expand Up @@ -86,6 +88,20 @@ export default ({ tab }: { sceneId: string; tab: Tab }) => {
[setCurrentCamera],
);

const handlePropertyValueUpdate = useCallback(
async (
propertyId?: string,
schemaItemId?: string,
fieldId?: string,
itemId?: string,
vt?: any,
v?: any,
) => {
if (!propertyId || !schemaItemId || !fieldId || !vt) return;
await useUpdatePropertyValue(propertyId, schemaItemId, itemId, fieldId, "en", v, vt);
},
[useUpdatePropertyValue],
);
return {
visualizerRef,
isVisualizerReady,
Expand All @@ -102,5 +118,6 @@ export default ({ tab }: { sceneId: string; tab: Tab }) => {
handleWidgetEditorToggle,
handleFlyTo,
handleCameraUpdate,
handlePropertyValueUpdate,
};
};
2 changes: 2 additions & 0 deletions web/src/beta/features/Editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const Editor: React.FC<Props> = ({ sceneId, projectId, workspaceId, tab }) => {
handleWidgetEditorToggle,
handleFlyTo,
handleCameraUpdate,
handlePropertyValueUpdate,
} = useHooks({ sceneId, tab });
const {
selectedStory,
Expand Down Expand Up @@ -135,6 +136,7 @@ const Editor: React.FC<Props> = ({ sceneId, projectId, workspaceId, tab }) => {
onSceneSettingSelect: handleSceneSettingSelected,
onDataSourceManagerOpen: handleDataSourceManagerOpener,
onFlyTo: handleFlyTo,
onPropertyUpdate: handlePropertyValueUpdate,
});

const { rightPanel } = useRightPanel({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { MouseEvent, useCallback, useState } from "react";

import TextInput from "@reearth/beta/components/fields/common/TextInput";
import ListItem from "@reearth/beta/components/ListItem";
import PopoverMenuContent from "@reearth/beta/components/PopoverMenuContent";
import Text from "@reearth/beta/components/Text";
import useDoubleClick from "@reearth/classic/util/use-double-click";
import { ValueType, ValueTypes } from "@reearth/classic/util/value";
import type { Page } from "@reearth/services/api/storytellingApi/utils";
import { useT } from "@reearth/services/i18n";
import { styled } from "@reearth/services/theme";

type PageItemProps = {
isSelected?: boolean;
title?: string;
isOpenAction?: boolean;
hasEmptySpace?: boolean;
propertyId: string;
storyPage: Page;
onItemClick: (e?: MouseEvent<Element>) => void;
onActionClick?: () => void;
onOpenChange?: (isOpen: boolean) => void;
setOpenedPageId?: (pageId: string | undefined) => void;
onPageDelete?: () => void;
onPropertyUpdate?: (
propertyId?: string,
schemaItemId?: string,
fieldId?: string,
itemId?: string,
vt?: ValueType,
v?: ValueTypes[ValueType],
) => Promise<void>;
};

const PageItem = ({
isSelected,
isOpenAction,
title,
hasEmptySpace,
propertyId,
storyPage,
onItemClick,
onActionClick,
onOpenChange,
setOpenedPageId,
onPageDelete,
onPropertyUpdate,
}: PageItemProps) => {
const t = useT();
const [isEditing, setIsEditing] = useState(false);
const [newValue, setNewValue] = useState(title);

const [handleSingleClick, handleDoubleClick] = useDoubleClick(
() => onItemClick?.(),
() => setIsEditing(true),
);

const handleChange = useCallback((newTitle: string) => setNewValue(newTitle), []);

const handleTitleSubmit = useCallback(() => {
setIsEditing(false);
if (newValue?.trim() !== "") {
const schemaGroupId = storyPage.property.items?.[1]?.schemaGroup;
onPropertyUpdate?.(propertyId, schemaGroupId, "title", undefined, "string", newValue);
}
}, [newValue, onPropertyUpdate, propertyId, storyPage.property.items]);

const handleEditExit = useCallback(
(e?: React.KeyboardEvent<HTMLInputElement>) => {
if (title !== newValue && e?.key !== "Escape") {
handleTitleSubmit();
} else {
setNewValue(title);
}
setIsEditing(false);
},
[title, newValue, handleTitleSubmit],
);

return (
<ListItem
border
actionPlacement="bottom-start"
isSelected={isSelected}
isOpenAction={isOpenAction}
onItemClick={handleSingleClick}
onActionClick={onActionClick}
onOpenChange={onOpenChange}
actionContent={
<PopoverMenuContent
size="sm"
items={[
// {
// icon: "copy",
// name: "Duplicate",
// onClick: () => {
// setOpenedPageId(undefined);
// onPageDuplicate(storyPage.id);
// },
// },
{
icon: "trash",
name: "Delete",
onClick: () => {
setOpenedPageId?.(undefined);
onPageDelete?.();
},
},
]}
/>
}>
{isEditing ? (
<StyledTextInput
value={newValue}
autoFocus
onChange={handleChange}
onExit={handleEditExit}
onBlur={handleEditExit}
/>
) : (
<PageTitle size="footnote" onDoubleClick={handleDoubleClick}>
{hasEmptySpace || !title ? t("Untitled") : title}
</PageTitle>
)}
</ListItem>
);
};

const StyledTextInput = styled(TextInput)`
width: 100%;
`;

const PageTitle = styled(Text)`
overflow: hidden;
width: 100%;
text-overflow: ellipsis;
`;

export default PageItem;
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { useEffect, useState } from "react";

import DragAndDropList from "@reearth/beta/components/DragAndDropList";
import ListItem from "@reearth/beta/components/ListItem";
import PopoverMenuContent from "@reearth/beta/components/PopoverMenuContent";
import Action from "@reearth/beta/features/Editor/tabs/story/LeftPanel/Action";
import PageItemWrapper from "@reearth/beta/features/Editor/tabs/story/LeftPanel/PageItemWrapper";
import { getFieldValue } from "@reearth/beta/lib/core/StoryPanel/utils";
import { isEmptyString } from "@reearth/beta/utils/util";
import { ValueType, ValueTypes } from "@reearth/beta/utils/value";
import type { Page } from "@reearth/services/api/storytellingApi/utils";
import { useT } from "@reearth/services/i18n";
import { styled } from "@reearth/services/theme";

import PageItem from "./PageItem";

type Props = {
storyPages: Page[];
selectedPageId?: string;
Expand All @@ -19,6 +20,14 @@ type Props = {
onPageDuplicate: (id: string) => void;
onPageDelete: (id: string) => void;
onPageMove: (id: string, targetIndex: number) => void;
onPropertyUpdate?: (
propertyId?: string,
schemaItemId?: string,
fieldId?: string,
itemId?: string,
vt?: ValueType,
v?: ValueTypes[ValueType],
) => Promise<void>;
};
const ContentPage: React.FC<Props> = ({
storyPages,
Expand All @@ -28,6 +37,7 @@ const ContentPage: React.FC<Props> = ({
// onPageDuplicate,
onPageDelete,
onPageMove,
onPropertyUpdate,
}) => {
const t = useT();
const [openedPageId, setOpenedPageId] = useState<string | undefined>(undefined);
Expand Down Expand Up @@ -67,42 +77,23 @@ const ContentPage: React.FC<Props> = ({
key={storyPage.id}
pageCount={i + 1}
isSwipeable={storyPage.swipeable}>
<ListItem
<PageItem
key={i}
border
actionPlacement="bottom-start"
isSelected={selectedPageId === storyPage.id}
isOpenAction={openedPageId === storyPage.id}
onItemClick={() => onPageSelect(storyPage.id)}
onActionClick={() => setOpenedPageId(old => (old ? undefined : storyPage.id))}
onOpenChange={isOpen => {
setOpenedPageId(isOpen ? storyPage.id : undefined);
}}
actionContent={
<PopoverMenuContent
size="sm"
items={[
// {
// icon: "copy",
// name: "Duplicate",
// onClick: () => {
// setOpenedPageId(undefined);
// onPageDuplicate(storyPage.id);
// },
// },
{
icon: "trash",
name: "Delete",
onClick: () => {
setOpenedPageId(undefined);
onPageDelete(storyPage.id);
},
},
]}
/>
}>
{hasEmptySpace || !title ? t("Untitled") : title}
</ListItem>
onPageDelete={() => onPageDelete(storyPage.id)}
hasEmptySpace={hasEmptySpace}
title={hasEmptySpace || !title ? t("Untitled") : title}
setOpenedPageId={setOpenedPageId}
propertyId={storyPage.property.id}
storyPage={storyPage}
onPropertyUpdate={onPropertyUpdate}
/>
</PageItemWrapper>
);
}}
Expand Down
11 changes: 11 additions & 0 deletions web/src/beta/features/Editor/tabs/story/LeftPanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import SidePanelCommon from "@reearth/beta/features/Editor/SidePanel";
import ContentPage from "@reearth/beta/features/Editor/tabs/story/LeftPanel/ContentPage";
import { ValueType, ValueTypes } from "@reearth/beta/utils/value";
import type { Story } from "@reearth/services/api/storytellingApi/utils";
import { useT } from "@reearth/services/i18n";

Expand All @@ -11,6 +12,14 @@ type Props = {
onPageDelete: (id: string) => void;
onPageAdd: (isSwipeable: boolean) => void;
onPageMove: (id: string, targetIndex: number) => void;
onPropertyUpdate?: (
propertyId?: string,
schemaItemId?: string,
fieldId?: string,
itemId?: string,
vt?: ValueType,
v?: ValueTypes[ValueType],
) => Promise<void>;
};

const StoryLeftPanel: React.FC<Props> = ({
Expand All @@ -21,6 +30,7 @@ const StoryLeftPanel: React.FC<Props> = ({
onPageDelete,
onPageAdd,
onPageMove,
onPropertyUpdate,
}) => {
const t = useT();

Expand All @@ -47,6 +57,7 @@ const StoryLeftPanel: React.FC<Props> = ({
onPageDuplicate={onPageDuplicate}
onPageDelete={onPageDelete}
onPageMove={onPageMove}
onPropertyUpdate={onPropertyUpdate}
/>
),
},
Expand Down
12 changes: 12 additions & 0 deletions web/src/beta/features/Editor/useLeftPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import MapSidePanel from "@reearth/beta/features/Editor/tabs/map/LeftPanel";
import StorySidePanel from "@reearth/beta/features/Editor/tabs/story/LeftPanel";
import { Tab } from "@reearth/beta/features/Navbar";
import { FlyTo } from "@reearth/beta/lib/core/types";
import { ValueType, ValueTypes } from "@reearth/beta/utils/value";
import type { NLSLayer } from "@reearth/services/api/layersApi/utils";
import type { Scene } from "@reearth/services/api/sceneApi";
import type { Story } from "@reearth/services/api/storytellingApi/utils";
Expand Down Expand Up @@ -36,6 +37,14 @@ type Props = {
onLayerSelect: (id: string) => void;
onDataSourceManagerOpen: () => void;
onFlyTo?: FlyTo;
onPropertyUpdate?: (
propertyId?: string,
schemaItemId?: string,
fieldId?: string,
itemId?: string,
vt?: ValueType,
v?: ValueTypes[ValueType],
) => Promise<void>;
};

export default ({
Expand All @@ -58,6 +67,7 @@ export default ({
onDataSourceManagerOpen,
onLayerVisibilityUpate,
onFlyTo,
onPropertyUpdate,
}: Props) => {
const leftPanel = useMemo<ReactNode | undefined>(() => {
switch (tab) {
Expand Down Expand Up @@ -87,6 +97,7 @@ export default ({
onPageDelete={onPageDelete}
onPageAdd={onPageAdd}
onPageMove={onPageMove}
onPropertyUpdate={onPropertyUpdate}
/>
);
case "widgets":
Expand Down Expand Up @@ -114,6 +125,7 @@ export default ({
onPageDelete,
onPageAdd,
onPageMove,
onPropertyUpdate,
]);

return {
Expand Down
Loading

0 comments on commit ccf3c25

Please sign in to comment.