fix: add read book

This commit is contained in:
godlike0108
2023-12-13 05:43:57 +08:00
parent 39ccc26942
commit aeee81f958
6 changed files with 106 additions and 15 deletions

View File

@@ -1,6 +1,6 @@
import { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { useNavigate, useSearchParams } from "react-router-dom";
import styled from "styled-components";
import {
currentSceneSelector,
@@ -145,6 +145,7 @@ const Scene = () => {
} = useSelector(currentSceneSelector);
const navigate = useNavigate();
const dispatch = useDispatch();
const [searchParams] = useSearchParams();
useEffect(() => {
if (sceneNumber) {
@@ -180,12 +181,16 @@ const Scene = () => {
}, [descriptions, sceneDescription]);
const onOptionClick = (val: string) => {
dispatch(
updateStory({
message: { role: StoryProgressPromptRole.User, content: val },
}),
);
setLoading(true);
if (searchParams.get("read") === "true") {
dispatch(toScene({ index: sceneNumber + 1 }));
} else {
dispatch(
updateStory({
message: { role: StoryProgressPromptRole.User, content: val },
}),
);
setLoading(true);
}
};
const onStoryEnd = async () => {
@@ -211,7 +216,11 @@ const Scene = () => {
convertUndefinedToNull(project),
);
// go to mint page
navigate(`/mint/${newProject.id}`);
const to =
searchParams.get("read") === "true"
? `/mint/${newProject.id}?read=true`
: `/mint/${newProject.id}`;
navigate(to);
};
if (loading) {

View File

@@ -1,5 +1,5 @@
import { Action } from "redux";
import { StoryProgress } from "../../types/story";
import { StoryProgress, Scene } from "../../types/story";
// Action Types
export const TO_SCENE = "Story/TO_SCENE";
@@ -7,6 +7,8 @@ export const INIT_STORY = "Story/INIT_STORY";
export const INIT_STORY_SUCCESS = "Story/INIT_STORY_SUCCESS";
export const UPDATE_STORY = "Story/UPDATE_STORY";
export const UPDATE_STORY_SUCCESS = "Story/UPDATE_STORY_SUCCESS";
export const LOAD_STORY = "Story/LOAD_STORY";
export const LOAD_STORY_SUCCESS = "Story/LOAD_STORY_SUCCESS";
// Action Creators
type ToSceneBody = { index: number };
@@ -52,6 +54,19 @@ export const updateStorySuccess = (data: UpdateStorySuccessBody) => ({
data,
});
type LoadStoryBody = {
storyProgressPrompts: StoryProgress[];
title: string;
introduction: string;
coverImage: string;
scenes: Scene[];
};
export type LoadStoryAction = Action & { data: LoadStoryBody };
export const loadStory = (data: LoadStoryBody): LoadStoryAction => ({
type: LOAD_STORY,
data,
});
export type StoryAction =
| ToSceneAction
| InitStoryAction

View File

@@ -6,6 +6,7 @@ import {
INIT_STORY_SUCCESS,
UPDATE_STORY,
UPDATE_STORY_SUCCESS,
LOAD_STORY,
} from "./actions";
import { parseStoryGuideline } from "./utils";
import { STORY_MOCK } from "../../mock";
@@ -79,6 +80,19 @@ const storyReducer = (state = initialState, action: StoryAction) => {
storyProgressPrompts: [...state.storyProgressPrompts, progress],
};
}
case LOAD_STORY: {
// when users fires their prompt to open AI, add the user role prompt into prompt list
const { storyProgressPrompts, title, introduction, coverImage, scenes } =
action.data;
return {
...state,
storyProgressPrompts,
title,
introduction,
coverImage,
scenes,
};
}
default:
return state;
}

View File

@@ -1,4 +1,6 @@
import { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import { Project } from "model";
import { format } from "date-fns";
import { collection, onSnapshot, query, where } from "firebase/firestore";
@@ -10,8 +12,13 @@ import {
PageContainer,
} from "../../components/Layout/Layout";
import styled from "styled-components";
import { Link } from "react-router-dom";
import { Link, Navigate } from "react-router-dom";
import { Button } from "@radix-ui/themes";
import {
createCharacterName,
createCharacterType,
} from "../../modules/character/actions";
import { loadStory } from "../../modules/story/actions";
export const StyledContentContainer = styled(ContentContainer)`
display: flex;
@@ -167,6 +174,9 @@ const StyledIndexTag = styled.div`
const DashboardPage = protectedRoute(({ user }: { user: User }) => {
const [projects, setProjects] = useState<Project[]>();
const dispatch = useDispatch();
const navigate = useNavigate();
useEffect(() => {
const myProjects = query(
collection(db, "projects"),
@@ -176,6 +186,29 @@ const DashboardPage = protectedRoute(({ user }: { user: User }) => {
setProjects(snapshot.docs.map((x) => x.data()) as Project[]);
});
}, [user.uid]);
const openBook = (value: Project) => {
const { character, rawPrompts, title, introduction, coverImage, scenes } =
value;
dispatch(createCharacterName({ characterName: character.name }));
dispatch(
createCharacterType({
characterType: character.type,
customCharacterType: character.customType,
}),
);
dispatch(
loadStory({
storyProgressPrompts: rawPrompts,
title,
introduction,
coverImage,
scenes,
}),
);
navigate("/story?read=true");
};
if (projects == null) {
return null;
}
@@ -208,7 +241,11 @@ const DashboardPage = protectedRoute(({ user }: { user: User }) => {
</StyledTitleContainer>
<StyledStoryContainer>
{projects.map((story, idx) => (
<StyledStoryItem>
<StyledStoryItem
onClick={() => {
openBook(story);
}}
>
<StyledStoryImage src={story.coverImage} alt="" />
<div>
<StyledInfo>

View File

@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { FC, useCallback, useEffect, useMemo, useState } from "react";
// import { useSearchParams } from "react-router-dom";
import { PageContainer } from "../../components/Layout/Layout";
import storyImg from "./_/story.png";
import styled from "styled-components";
@@ -65,6 +66,10 @@ const StyledCreateButtonContainer = styled.div`
const MinStoryPage: FC = () => {
const projectId = useParams().projectId!;
const [project, setProject] = useState<DocumentSnapshot<Project>>();
// const [searchParams] = useSearchParams();
// const readMode = searchParams.get("read") === "true";
useEffect(() => {
return onSnapshot(doc(db, "projects", projectId), (doc) =>
setProject(doc as any as DocumentSnapshot<Project>),
@@ -96,9 +101,20 @@ const MinStoryPage: FC = () => {
</StyledDescription>
<StyledCreateButtonContainer>
<SuiMintButton projectId={projectId} />
<EVM projectId={projectId}>
<StyledCreateButton>Mint Story (Avax)</StyledCreateButton>
</EVM>
{project?.data()?.minted ? (
<StyledCreateButton
style={{
color: "white",
backgroundColor: "green",
}}
>
Minted! (Avax)
</StyledCreateButton>
) : (
<EVM projectId={projectId}>
<StyledCreateButton>Mint Story (Avax)</StyledCreateButton>
</EVM>
)}
</StyledCreateButtonContainer>
</StyledInfoContainer>
</StyledStoryItem>

2
model/model.d.ts vendored
View File

@@ -1,4 +1,4 @@
export type Character = { type: string; name: string };
export type Character = { type: string; name: string; customType: string };
// user/{uid}/projects/{projectId}