feat: adding images

This commit is contained in:
godlike0108
2023-12-12 17:57:54 +08:00
parent 37d0abf7aa
commit b1c69ca6bf
7 changed files with 205 additions and 40 deletions

View File

@@ -1,10 +1,28 @@
import { useDispatch, useSelector } from "react-redux";
import { Container, Heading } from "@radix-ui/themes";
import styled from "styled-components";
import { toScene } from "../modules/story/actions";
import { storySelector } from "../modules/story/selectors";
const BackgroundImageContainer = styled.div<{ backgroundImageUrl: string }>`
background-image: url(${(props) => props.backgroundImageUrl});
background-size: cover;
background-position: center;
height: 100vh; // Full height of the viewport
width: 100%; // Full width of the viewport
display: flex;
justify-content: center;
align-items: center; // Center the content vertically and horizontally
text-align: center;
`;
const Heading = styled.h1`
font-size: 4rem; /* Large font size */
color: white; /* White text color */
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); /* Text shadow for better readability */
`;
const Cover = () => {
const { title, currentSceneIndex } = useSelector(storySelector);
const { title, coverImage, currentSceneIndex } = useSelector(storySelector);
const dispatch = useDispatch();
const next = () => {
@@ -13,10 +31,13 @@ const Cover = () => {
};
return (
<Container onClick={next}>
<BackgroundImageContainer backgroundImageUrl={coverImage} onClick={next}>
<Heading>{title}</Heading>
<Heading as="h4">image here</Heading>
</Container>
</BackgroundImageContainer>
// <Container onClick={next}>
// <Heading>{title}</Heading>
// <img src={coverImage} />
// </Container>
);
};

View File

@@ -1,15 +1,88 @@
import { useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { Container, Heading } from "@radix-ui/themes";
import {
storySelector,
currentSceneSelector,
} from "../modules/story/selectors";
import { updateStory } from "../modules/story/actions";
import styled from "styled-components";
import { currentSceneSelector } from "../modules/story/selectors";
import { updateStory, toScene } from "../modules/story/actions";
import { StoryProgressPromptRole } from "../types/story";
const Cover = () => {
// const { currentSceneIndex } = useSelector(storySelector);
const { sceneTitle, sceneDescription, optionPrompt, options } =
const BackgroundImageContainer = styled.div<{ backgroundImageUrl: string }>`
background-image: url(${(props) => props.backgroundImageUrl});
background-size: cover;
background-position: center;
height: 100vh; // Full height of the viewport
width: 100%; // Full width of the viewport
display: flex;
justify-content: center;
align-items: center; // Center the content vertically and horizontally
text-align: center;
`;
const QuoteContainer = styled.div`
background: linear-gradient(
0deg,
rgba(24, 24, 24, 0.8),
rgba(24, 24, 24, 0.8)
),
linear-gradient(0deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.1));
font-size: 24px; /* Adjust as needed */
width: 90%; /* Adjust as needed */
position: absolute;
bottom: 100px; /* Adjust as needed */
left: 50%;
transform: translateX(-50%);
padding: 28px;
`;
const QuoteText = styled.p`
color: #ffffff;
font-size: 24px; /* Adjust as needed */
`;
const ButtonContainer = styled.div`
display: flex;
gap: 24px;
justify-content: flex-end;
align-items: center;
`;
const Button = styled.button`
background-color: #000000; /* Adjust as needed */
color: #ffffff;
border: none;
padding: 10px 20px; /* Adjust as needed */
cursor: pointer;
`;
const OptionButtonContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px;
gap: 10px; /* Space between options */
`;
const OptionButton = styled.button`
background-color: rgba(0, 0, 0, 0.7); /* Semi-transparent black */
color: white;
border: none;
border-radius: 20px; /* Rounded corners */
padding: 10px 30px;
text-align: center;
font-size: 16px;
cursor: pointer;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); /* Box shadow for a 3D effect */
text-transform: uppercase; /* Uppercase text */
width: 200px; /* Fixed width, adjust as needed */
&:hover {
background-color: rgba(0, 0, 0, 0.8); /* Darken button on hover */
}
`;
const Scene = () => {
const [step, setStep] = useState(0); // note: 0 is description, 1 is options
const { sceneNumber, sceneDescription, sceneImage, optionPrompt, options } =
useSelector(currentSceneSelector);
const dispatch = useDispatch();
@@ -22,21 +95,50 @@ const Cover = () => {
};
return (
<Container>
<Heading>{sceneTitle}</Heading>
<Heading as="h4">{sceneDescription}</Heading>
<Heading as="h4">{optionPrompt}</Heading>
{options && options.length && (
<ul>
{options.map((option, oidx) => (
<li key={oidx} onClick={() => onOptionClick(option)}>
{option}
</li>
))}
</ul>
<BackgroundImageContainer backgroundImageUrl={sceneImage}>
{step === 0 && (
<QuoteContainer>
<QuoteText>{sceneDescription}</QuoteText>
<ButtonContainer>
<Button
onClick={() => {
dispatch(toScene({ index: sceneNumber - 1 }));
}}
>
Back
</Button>
{options && options.length && (
<Button
onClick={() => {
setStep(1);
}}
>
Next
</Button>
)}
</ButtonContainer>
</QuoteContainer>
)}
</Container>
{step === 1 && (
<>
{options && options.length && (
<OptionButtonContainer>
{options.map((opt) => (
<OptionButton key={opt} onClick={() => onOptionClick(opt)}>
{opt}
</OptionButton>
))}
</OptionButtonContainer>
)}
{optionPrompt && (
<QuoteContainer>
<QuoteText>{optionPrompt}</QuoteText>
</QuoteContainer>
)}
</>
)}
</BackgroundImageContainer>
);
};
export default Cover;
export default Scene;

View File

@@ -2,7 +2,7 @@
import * as ReactDOM from "react-dom/client";
import "@mysten/dapp-kit/dist/index.css";
import "@radix-ui/themes/styles.css";
import "./index.css";
// import "./index.css";
import { getFullnodeUrl } from "@mysten/sui.js/client";
import {
createNetworkConfig,

File diff suppressed because one or more lines are too long

View File

@@ -37,19 +37,22 @@ function* initStory(action: InitStoryAction) {
);
const progress = data.choices?.[0].message as StoryProgress;
const { introduction, scene } = parseStoryGuideline(progress.content);
const coverImage = (yield call(
const { image_url } = (yield call(
callFunction,
"generateImage",
introduction,
)) as string;
console.log(coverImage);
const scene1Image = (yield call(
)) as { image_url: string; revised_prompt: string };
const { image_url: scene1Image } = (yield call(
callFunction,
"generateImage",
scene.sceneDescription,
)) as string;
)) as { image_url: string; revised_prompt: string };
yield put(
initStorySuccess({ progress, coverImage, sceneImage: scene1Image }),
initStorySuccess({
progress,
coverImage: image_url,
sceneImage: scene1Image,
}),
);
} catch (e) {
console.error(e);
@@ -82,12 +85,12 @@ function* updateStory(action: InitStoryAction) {
);
const progress = data.choices?.[0].message as StoryProgress;
const { sceneDescription } = parseScene(progress.content);
const sceneImage = (yield call(
const { image_url } = (yield call(
callFunction,
"generateImage",
sceneDescription,
)) as string;
yield put(updateStorySuccess({ progress, sceneImage }));
)) as { image_url: string; revised_prompt: string };
yield put(updateStorySuccess({ progress, sceneImage: image_url }));
} catch (e) {
console.error(e);
} finally {

View File

@@ -44,7 +44,8 @@ export const parseStoryGuideline = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let cont: any = {};
try {
cont = JSON.parse(content) as RawScene;
const markdownStripped = stripMarkdown(content);
cont = JSON.parse(markdownStripped) as RawScene;
} catch (e) {
console.log(e);
}

3
model/model.d.ts vendored
View File

@@ -29,7 +29,8 @@ export type Project = {
createdAt: number;
minted: boolean;
title: string;
image: string;
introduction: string;
coverImage: string;
rawPrompts: RawPrompt[];
};