mirror of
https://github.com/placeholder-soft/storytime.git
synced 2026-01-12 07:14:55 +08:00
fix: add read book
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
2
model/model.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
export type Character = { type: string; name: string };
|
||||
export type Character = { type: string; name: string; customType: string };
|
||||
|
||||
// user/{uid}/projects/{projectId}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user