Skip to content

Commit

Permalink
chore(web): Add story background setting (#775)
Browse files Browse the repository at this point in the history
Co-authored-by: nina992 <nouralali992@gmail.com>
  • Loading branch information
nina992 and nina992 committed Nov 8, 2023
1 parent 8aa78f7 commit f8ea057
Show file tree
Hide file tree
Showing 18 changed files with 74 additions and 45 deletions.
4 changes: 2 additions & 2 deletions web/src/beta/components/fields/ColorField/index.tsx
Expand Up @@ -16,7 +16,7 @@ import { Props, RGBA } from "./types";
const channels = ["r", "g", "b", "a"];
const hexPlaceholder = "#RRGGBBAA";

const ColorField: React.FC<Props> = ({ name, description, value, onChange }) => {
const ColorField: React.FC<Props> = ({ name, description, value, onChange, className }) => {
const t = useT();
const theme = useTheme();
const {
Expand All @@ -37,7 +37,7 @@ const ColorField: React.FC<Props> = ({ name, description, value, onChange }) =>
} = useHooks({ value, onChange });

return (
<Property name={name} description={description}>
<Property name={name} description={description} className={className}>
<Wrapper ref={wrapperRef}>
<Popover.Provider open={open} placement="bottom-start">
<Popover.Trigger asChild>
Expand Down
1 change: 1 addition & 0 deletions web/src/beta/components/fields/ColorField/types.ts
@@ -1,5 +1,6 @@
// Component Props
export type Props = {
className?: string;
name?: string;
description?: string;
value?: string;
Expand Down
4 changes: 3 additions & 1 deletion web/src/beta/components/fields/SelectField/index.tsx
Expand Up @@ -14,6 +14,7 @@ export type SelectValue = {
};

export type Props = {
className?: string;
options?: SelectValue[];
onChange: (key: string) => void;
value?: string;
Expand All @@ -25,6 +26,7 @@ export type Props = {
};

const SelectField: React.FC<Props> = ({
className,
options,
onChange,
value,
Expand All @@ -51,7 +53,7 @@ const SelectField: React.FC<Props> = ({
}, [options, value]);

return (
<Property name={name} description={description}>
<Property name={name} description={description} className={className}>
<Popover.Provider open={open} placement="bottom-start" onOpenChange={handlePopOver}>
<Popover.Trigger asChild>
<InputWrapper disabled={disabled} onClick={handlePopOver}>
Expand Down
5 changes: 3 additions & 2 deletions web/src/beta/components/fields/index.tsx
Expand Up @@ -8,11 +8,12 @@ type Props = {
name?: string;
description?: string;
children: ReactNode;
className?: string;
};

const Property: React.FC<Props> = ({ name, description, children }) => {
const Property: React.FC<Props> = ({ name, description, children, className }) => {
return (
<Wrapper>
<Wrapper className={className}>
{name && <Text size="footnote">{name}</Text>}
{children}
{description && (
Expand Down
1 change: 1 addition & 0 deletions web/src/beta/features/Editor/Visualizer/convert-story.ts
Expand Up @@ -41,6 +41,7 @@ export const convertStory = (story?: GqlStory): Story | undefined => {
id: story.id,
title: story.title,
position: story.panelPosition === "RIGHT" ? "right" : "left",
bgColor: story.bgColor ?? "#f1f1f1",
pages: storyPages(story.pages),
};
};
Expand Down
1 change: 0 additions & 1 deletion web/src/beta/features/Editor/Visualizer/hooks.ts
Expand Up @@ -205,7 +205,6 @@ export default ({
() => convertStory(scene?.stories.find(s => s.id === storyId)),
[storyId, scene?.stories],
);

const handleCurrentPageChange = useCallback(
(pageId?: string) => selectSelectedStoryPageId(pageId),
[selectSelectedStoryPageId],
Expand Down
16 changes: 4 additions & 12 deletions web/src/beta/features/ProjectSettings/hooks.ts
Expand Up @@ -22,7 +22,7 @@ type Props = {
subId?: string;
};

export default ({ projectId, tab, subId }: Props) => {
export default ({ projectId, tab }: Props) => {
const navigate = useNavigate();

const {
Expand Down Expand Up @@ -80,17 +80,9 @@ export default ({ projectId, tab, subId }: Props) => {
},
[projectId, useUpdateProjectAlias],
);

const stories = useMemo(() => scene?.stories ?? [], [scene?.stories]);
const currentStory = useMemo(
() =>
tab === "story"
? stories.find(s => s.id === subId) ?? stories[0]
: tab === "public"
? stories.find(s => s.id === subId)
: undefined,
[tab, subId, stories],
);
const { useStoriesQuery } = useStorytellingAPI();
const { stories = [] } = useStoriesQuery({ sceneId: scene?.id });
const currentStory = useMemo(() => (stories?.length ? stories[0] : undefined), [stories]);

const { useUpdateStory } = useStorytellingAPI();
const handleUpdateStory = useCallback(
Expand Down
@@ -1,6 +1,6 @@
import { useMemo } from "react";

import { Story } from "@reearth/services/gql";
import { Story } from "@reearth/services/api/storytellingApi/utils";
import { useT } from "@reearth/services/i18n";

import { MenuItem } from "../../MenuList";
Expand Down
Expand Up @@ -2,9 +2,11 @@ import { useCallback, useState } from "react";

import Button from "@reearth/beta/components/Button";
import Collapse from "@reearth/beta/components/Collapse";
import ColorField from "@reearth/beta/components/fields/ColorField";
import SelectField from "@reearth/beta/components/fields/SelectField";
import { Position } from "@reearth/services/gql";
import { useT } from "@reearth/services/i18n";
import { styled } from "@reearth/services/theme";

import { SettingsFields, ButtonWrapper } from "../common";

Expand All @@ -21,12 +23,13 @@ const StorySettingsDetail: React.FC<Props> = ({ settingsItem, onUpdateStory }) =
const [localPanelPosition, setLocalPanelPosition] = useState<Position | undefined>(
settingsItem.panelPosition,
);

const [backgroundColor, setBackgroundColor] = useState<string | undefined>(settingsItem?.bgColor);
const handleSubmit = useCallback(() => {
onUpdateStory({
panelPosition: localPanelPosition,
bgColor: backgroundColor,
});
}, [localPanelPosition, onUpdateStory]);
}, [backgroundColor, localPanelPosition, onUpdateStory]);

const options = [
{
Expand All @@ -42,12 +45,19 @@ const StorySettingsDetail: React.FC<Props> = ({ settingsItem, onUpdateStory }) =
return (
<Collapse title={t("Story Panel")} alwaysOpen>
<SettingsFields>
<SelectField
name={t("Panel Position")}
value={localPanelPosition}
options={options}
onChange={value => setLocalPanelPosition(value as Position)}
/>
<FieldsWrapper>
<SelectFieldWrapper
name={t("Panel Position")}
value={localPanelPosition}
options={options}
onChange={value => setLocalPanelPosition(value as Position)}
/>
<ColorFieldWrapper
name={t("Background Color")}
value={backgroundColor}
onChange={value => setBackgroundColor(value)}
/>
</FieldsWrapper>
<ButtonWrapper>
<Button
text={t("Submit")}
Expand All @@ -63,3 +73,16 @@ const StorySettingsDetail: React.FC<Props> = ({ settingsItem, onUpdateStory }) =
};

export default StorySettingsDetail;

const FieldsWrapper = styled.div`
display: flex;
justify-content: space-between;
flex-direction: row;
gap: 8px;
`;
const SelectFieldWrapper = styled(SelectField)`
width: 100%;
`;
const ColorFieldWrapper = styled(ColorField)`
width: 100%;
`;
@@ -1,6 +1,6 @@
import { useMemo } from "react";

import { Position, Story } from "@reearth/services/gql";
import { Position, Story } from "@reearth/services/api/storytellingApi/utils";

import { MenuItem } from "../../MenuList";
import { InnerPage, InnerMenu, SettingsWrapper, ArchivedSettingNotice } from "../common";
Expand All @@ -9,6 +9,7 @@ import StorySettingsDetail from "./StorySettingsDetail";

export type StorySettingsType = {
panelPosition?: Position;
bgColor?: string;
};

type Props = {
Expand All @@ -35,7 +36,6 @@ const StorySettings: React.FC<Props> = ({
})),
[stories, projectId],
);

return (
<InnerPage wide>
<InnerMenu>
Expand All @@ -54,7 +54,10 @@ const StorySettings: React.FC<Props> = ({
) : (
<StorySettingsDetail
key={currentStory.id}
settingsItem={currentStory}
settingsItem={{
panelPosition: currentStory.panelPosition,
bgColor: currentStory.bgColor,
}}
onUpdateStory={onUpdateStory}
/>
)}
Expand Down
1 change: 1 addition & 0 deletions web/src/beta/features/PublishedVisualizer/hooks.ts
Expand Up @@ -153,6 +153,7 @@ export default (alias?: string) => {
id: s.id,
title: s.title,
position: s.position,
bgColor: s.bgColor,
pages: s.pages.map(p => {
return {
id: p.id,
Expand Down
1 change: 1 addition & 0 deletions web/src/beta/features/PublishedVisualizer/types.ts
Expand Up @@ -19,6 +19,7 @@ export type Story = {
title?: string;
position: "left" | "right";
pages: StoryPage[];
bgColor?: string;
};

export type StoryPage = {
Expand Down
7 changes: 3 additions & 4 deletions web/src/beta/lib/core/StoryPanel/index.tsx
Expand Up @@ -77,9 +77,8 @@ export const StoryPanel = memo(
},
ref,
);

return (
<PanelWrapper>
<PanelWrapper bgColor={selectedStory?.bgColor}>
{!!pageInfo && (
<PageIndicator
currentPage={pageInfo.currentPage}
Expand Down Expand Up @@ -114,8 +113,8 @@ export const StoryPanel = memo(

export default StoryPanel;

const PanelWrapper = styled.div`
const PanelWrapper = styled.div<{ bgColor?: string }>`
flex: 0 0 ${STORY_PANEL_WIDTH}px;
background: #f1f1f1;
background: ${({ bgColor }) => bgColor};
color: ${({ theme }) => theme.content.weak};
`;
1 change: 1 addition & 0 deletions web/src/beta/lib/core/StoryPanel/types.ts
Expand Up @@ -3,6 +3,7 @@ export type Position = "left" | "right";
export type Story = {
id: string;
title?: string;
bgColor?: string;
position: Position;
pages: StoryPage[];
};
Expand Down
14 changes: 9 additions & 5 deletions web/src/services/api/storytellingApi/utils.ts
Expand Up @@ -23,30 +23,34 @@ export type Page = {
blocks?: Block[];
layersIds?: string[];
};

export enum Position {
Left = "LEFT",
Right = "RIGHT",
}
export type Story = {
id: string;
title?: string;
bgColor?: string;
publicTitle?: string;
publicDescription?: string;
publicImage?: string;
isBasicAuthActive?: boolean;
basicAuthUsername?: string;
basicAuthPassword?: string;
publishmentStatus?: string;
panelPosition?: "left" | "right";
alias?: string;
panelPosition?: Position;
alias: string;
pages?: Page[];
};

export const getStories = (rawScene?: GetSceneQuery) => {
const scene = rawScene?.node?.__typename === "Scene" ? rawScene.node : undefined;

return scene?.stories.map(s => {
return {
...s,
publishmentStatus: s.publishmentStatus,
panelPosition: s.panelPosition === "RIGHT" ? "right" : "left",
panelPosition: s.panelPosition,
bgColor: s.bgColor,
pages: s.pages.map(p => {
return {
...p,
Expand Down
4 changes: 2 additions & 2 deletions web/src/services/gql/__gen__/gql.ts
Expand Up @@ -24,7 +24,7 @@ const documents = {
"\n fragment PluginFragment on Plugin {\n id\n name\n extensions {\n extensionId\n description\n name\n translatedDescription(lang: $lang)\n translatedName(lang: $lang)\n icon\n singleOnly\n type\n widgetLayout {\n extendable {\n vertically\n horizontally\n }\n extended\n floating\n defaultLocation {\n zone\n section\n area\n }\n }\n }\n }\n": types.PluginFragmentFragmentDoc,
"\n fragment ProjectFragment on Project {\n id\n name\n description\n imageUrl\n isArchived\n isBasicAuthActive\n basicAuthUsername\n basicAuthPassword\n publicTitle\n publicDescription\n publicImage\n alias\n publishmentStatus\n updatedAt\n coreSupport\n }\n": types.ProjectFragmentFragmentDoc,
"\n fragment PropertySchemaFieldFragment on PropertySchemaField {\n fieldId\n title\n description\n translatedTitle(lang: $lang)\n translatedDescription(lang: $lang)\n prefix\n suffix\n type\n defaultValue\n ui\n min\n max\n choices {\n key\n icon\n title\n translatedTitle(lang: $lang)\n }\n isAvailableIf {\n fieldId\n type\n value\n }\n }\n\n fragment PropertySchemaGroupFragment on PropertySchemaGroup {\n schemaGroupId\n title\n collection\n translatedTitle(lang: $lang)\n isList\n representativeFieldId\n isAvailableIf {\n fieldId\n type\n value\n }\n fields {\n ...PropertySchemaFieldFragment\n }\n }\n\n fragment PropertyFieldFragment on PropertyField {\n id\n fieldId\n type\n value\n links {\n ...PropertyFieldLink\n }\n }\n\n fragment PropertyGroupFragment on PropertyGroup {\n id\n schemaGroupId\n fields {\n ...PropertyFieldFragment\n }\n }\n\n fragment PropertyItemFragment on PropertyItem {\n ... on PropertyGroupList {\n id\n schemaGroupId\n groups {\n ...PropertyGroupFragment\n }\n }\n ... on PropertyGroup {\n ...PropertyGroupFragment\n }\n }\n\n fragment PropertyFragmentWithoutSchema on Property {\n id\n items {\n ...PropertyItemFragment\n }\n }\n\n fragment PropertyFragment on Property {\n id\n ...PropertyFragmentWithoutSchema\n schema {\n id\n groups {\n ...PropertySchemaGroupFragment\n }\n }\n }\n\n fragment MergedPropertyGroupCommonFragment on MergedPropertyGroup {\n schemaGroupId\n fields {\n fieldId\n type\n actualValue\n overridden\n links {\n ...PropertyFieldLink\n }\n }\n }\n\n fragment MergedPropertyGroupFragment on MergedPropertyGroup {\n ...MergedPropertyGroupCommonFragment\n groups {\n ...MergedPropertyGroupCommonFragment\n }\n }\n\n fragment MergedPropertyFragmentWithoutSchema on MergedProperty {\n originalId\n parentId\n linkedDatasetId\n groups {\n ...MergedPropertyGroupFragment\n }\n }\n\n fragment MergedPropertyFragment on MergedProperty {\n ...MergedPropertyFragmentWithoutSchema\n schema {\n id\n }\n }\n\n fragment PropertyFieldLink on PropertyFieldLink {\n datasetId\n datasetSchemaId\n datasetSchemaFieldId\n }\n": types.PropertySchemaFieldFragmentFragmentDoc,
"\n fragment StoryFragment on Story {\n id\n title\n panelPosition\n isBasicAuthActive\n basicAuthUsername\n basicAuthPassword\n alias\n publicTitle\n publicDescription\n publishmentStatus\n publicImage\n publicNoIndex\n pages {\n ...StoryPageFragment\n }\n }\n": types.StoryFragmentFragmentDoc,
"\n fragment StoryFragment on Story {\n id\n title\n panelPosition\n bgColor\n isBasicAuthActive\n basicAuthUsername\n basicAuthPassword\n alias\n publicTitle\n publicDescription\n publishmentStatus\n publicImage\n publicNoIndex\n pages {\n ...StoryPageFragment\n }\n }\n": types.StoryFragmentFragmentDoc,
"\n fragment StoryPageFragment on StoryPage {\n id\n title\n swipeable\n propertyId\n property {\n id\n ...PropertyFragment\n }\n layersIds\n blocks {\n id\n pluginId\n extensionId\n property {\n id\n ...PropertyFragment\n }\n }\n }\n": types.StoryPageFragmentFragmentDoc,
"\n query GetAssets($teamId: ID!, $sort: AssetSortType, $keyword: String, $pagination: Pagination) {\n assets(teamId: $teamId, keyword: $keyword, sort: $sort, pagination: $pagination) {\n edges {\n cursor\n node {\n id\n teamId\n name\n size\n url\n contentType\n }\n }\n nodes {\n id\n teamId\n name\n size\n url\n contentType\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n totalCount\n }\n }\n": types.GetAssetsDocument,
"\n mutation CreateAsset($teamId: ID!, $file: Upload!) {\n createAsset(input: { teamId: $teamId, file: $file }) {\n asset {\n id\n teamId\n name\n size\n url\n contentType\n }\n }\n }\n": types.CreateAssetDocument,
Expand Down Expand Up @@ -138,7 +138,7 @@ export function gql(source: "\n fragment PropertySchemaFieldFragment on Propert
/**
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function gql(source: "\n fragment StoryFragment on Story {\n id\n title\n panelPosition\n isBasicAuthActive\n basicAuthUsername\n basicAuthPassword\n alias\n publicTitle\n publicDescription\n publishmentStatus\n publicImage\n publicNoIndex\n pages {\n ...StoryPageFragment\n }\n }\n"): (typeof documents)["\n fragment StoryFragment on Story {\n id\n title\n panelPosition\n isBasicAuthActive\n basicAuthUsername\n basicAuthPassword\n alias\n publicTitle\n publicDescription\n publishmentStatus\n publicImage\n publicNoIndex\n pages {\n ...StoryPageFragment\n }\n }\n"];
export function gql(source: "\n fragment StoryFragment on Story {\n id\n title\n panelPosition\n bgColor\n isBasicAuthActive\n basicAuthUsername\n basicAuthPassword\n alias\n publicTitle\n publicDescription\n publishmentStatus\n publicImage\n publicNoIndex\n pages {\n ...StoryPageFragment\n }\n }\n"): (typeof documents)["\n fragment StoryFragment on Story {\n id\n title\n panelPosition\n bgColor\n isBasicAuthActive\n basicAuthUsername\n basicAuthPassword\n alias\n publicTitle\n publicDescription\n publishmentStatus\n publicImage\n publicNoIndex\n pages {\n ...StoryPageFragment\n }\n }\n"];
/**
* The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down

0 comments on commit f8ea057

Please sign in to comment.