create storyPage
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
NekoVari 2025-05-06 15:36:55 +07:00
parent 673c1f3ec0
commit 8de6e9d771
8 changed files with 153 additions and 59 deletions

View file

@ -1,7 +1,7 @@
- id: 1 - id: 1
type: story type: story
text: "During break, you go out into the hallway for some air, then someone approaches you with a smile." text: "During break, you go out into the hallway for some air, then someone approaches you with a smile."
background: "" background: "bg-hallway.png"
goTo: 2 goTo: 2
- id: 2 - id: 2

View file

@ -26,6 +26,9 @@ body {
.title.medium{ .title.medium{
font-size: 24pt; font-size: 24pt;
} }
.title.small{
font-size: 16pt;
}
.body { .body {
font-family: "Source Sans 3"; font-family: "Source Sans 3";
@ -33,3 +36,9 @@ body {
font-weight: 400; font-weight: 400;
text-align: center; text-align: center;
} }
@media (max-width: 768px) {
.title {
font-size: 16pt;
}
}

21
src/css/textBox.css Normal file
View file

@ -0,0 +1,21 @@
.textBox {
display: flex;
justify-content: center;
align-items: center;
width: 60vw;
background-color: white;
color: #8391b8;
border-style: solid;
border-color: #8391b8;
border-width: 5px;
border-radius: 30px;
}
@media (max-width: 768px) {
.textBox.title {
margin-top: 50vh;
}
.textBox.title.small {
margin-top: 50vh;
}
}

View file

@ -9,7 +9,7 @@ import NamePage from './pages/namePage.jsx';
import Animation from './pages/components/animation.jsx'; import Animation from './pages/components/animation.jsx';
import IntroductionPage from './pages/introductionPage.jsx'; import IntroductionPage from './pages/introductionPage.jsx';
import PlayVideo from './pages/components/playVideo.jsx' import PlayVideo from './pages/components/playVideo.jsx'
import StoryPage from './pages/storyPage.jsx'; import VitualNovelHandler from './pages/vistualNovelHandler.jsx';
createRoot(document.getElementById('root')).render( createRoot(document.getElementById('root')).render(
<StrictMode> <StrictMode>
@ -21,7 +21,7 @@ createRoot(document.getElementById('root')).render(
<Route path="/sprite" element={<Animation />} /> <Route path="/sprite" element={<Animation />} />
<Route path='/video' element={<PlayVideo />} /> <Route path='/video' element={<PlayVideo />} />
<Route path="/introduction" element={<IntroductionPage />} /> <Route path="/introduction" element={<IntroductionPage />} />
<Route path='/story' element={<StoryPage />} /> <Route path='/vs/:step' element={<VitualNovelHandler />} />
<Route path="*" element={<Navigate to="/" replace />} /> <Route path="*" element={<Navigate to="/" replace />} />
</Routes> </Routes>

View file

@ -7,9 +7,7 @@ export const fetchYamlData = async ({ src = '/yml/DialogPorsche.yml' }) => {
throw new Error('Network response was not ok'); throw new Error('Network response was not ok');
} }
const yamlData = await response.text(); const yamlData = await response.text();
console.log('Fetched YAML data:', yamlData); // Debugging statement
const parsedData = yaml.load(yamlData); const parsedData = yaml.load(yamlData);
console.log('Parsed YAML data:', parsedData); // Debugging statement
return parsedData; return parsedData;
} catch (error) { } catch (error) {
throw new Error(`Error loading YAML data: ${error.message}`); throw new Error(`Error loading YAML data: ${error.message}`);

View file

@ -0,0 +1,34 @@
// src/ConversationPage.js
import { useEffect, useState } from 'react';
import '../css/global.css';
import '../css/textBox.css';
function ConversationPage({data , onClicked}) {
const backgroundSRC = `${import.meta.env.VITE_ASSETS_URL}/${data.background}`
return (
<div
onClick={onClicked}
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100vh',
width: '100vw',
flexDirection: 'column',
backgroundImage: `url(${backgroundSRC})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
>
<div className='nameBox title'>
{data.name}
</div>
<div className='textBox title' style={{marginTop: '50vh', overflow: 'scroll',}}>
{data.text}
</div>
</div>
);
}
export default ConversationPage;

View file

@ -1,72 +1,28 @@
// src/StoryPage.js // src/StoryPage.js
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import '../css/global.css'; import '../css/global.css';
import { fetchYamlData } from './components/fetchYamlData'; import '../css/textBox.css';
function StoryPage() { function StoryPage({data , onClicked}) {
const [data, setData] = useState(null); const backgroundSRC = `${import.meta.env.VITE_ASSETS_URL}/${data.background}`
const [error, setError] = useState(null);
const [currentStep, setCurrentStep] = useState(0);
useEffect(() => {
const loadData = async () => {
try {
const parsedData = await fetchYamlData({ src: '/yml/DialogPorsche.yml' });
console.log("Parsed in component:", parsedData);
if (!Array.isArray(parsedData)) {
throw new Error('YAML data is not an array');
}
setData(parsedData);
} catch (error) {
setError(error.message);
}
};
loadData();
}, []);
if (error) {
return <div>Error loading YAML data: {error}</div>;
}
if (!data) {
return <div>Loading...</div>;
}
const handleClicked = () => {
console.log(data);
// You can add logic here to handle the click event, such as navigating to the next step
if (currentStep < data.length - 1) {
setCurrentStep(currentStep + 1);
}
};
const currentStepData = data[currentStep];
return ( return (
<div <div
onClick={handleClicked} onClick={onClicked}
style={{ style={{
display: 'flex', display: 'flex',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
height: '100vh', height: '100vh',
width: '100vw',
flexDirection: 'column', flexDirection: 'column',
backgroundImage: `url(${backgroundSRC})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}} }}
> >
<label className='title'>Fifty Shades <br /> of Bully</label> <div className='textBox title' style={{marginTop: '50vh', overflow: 'scroll',}}>
<div> {data.text}
<p>ID: {currentStepData.id}</p>
<p>Type: {currentStepData.type}</p>
{currentStepData.name && <p>Name: {currentStepData.name}</p>}
<p>Text: {currentStepData.text}</p>
{currentStepData.option && (
<ul>
{currentStepData.option.map((option, index) => (
<li key={index}>{option.text}</li>
))}
</ul>
)}
</div> </div>
</div> </div>
); );

View file

@ -0,0 +1,76 @@
// src/pages/vistualNovelHandler.jsx
import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import '../css/global.css';
import { fetchYamlData } from './components/fetchYamlData';
import StoryPage from './storyPage';
import LoadingScene from './components/loadingScene.jsx';
function VitualNovelHandler() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [currentStep, setCurrentStep] = useState(0);
const navigate = useNavigate();
const { step } = useParams();
useEffect(() => {
const loadData = async () => {
try {
const parsedData = await fetchYamlData({ src: '/yml/DialogPorsche.yml' });
if (!Array.isArray(parsedData)) {
throw new Error('YAML data is not an array');
}
setData(parsedData);
} catch (error) {
setError(error.message);
}
};
loadData();
}, []);
useEffect(() => {
// Update the current step from the URL parameter
if (step && !isNaN(step)) {
setCurrentStep(parseInt(step, 10));
}
}, [step]);
if (error) {
return <div>Error loading YAML data: {error}</div>;
}
if (!data) {
return <div>Loading...</div>;
}
const handleNextStep = () => {
console.log(data);
if (currentStep < data.length - 1) {
setCurrentStep(currentStep + 1);
navigate(`/vs/${currentStep + 1}`);
}
};
const currentStepData = data[currentStep];
const renderComponent = (type) => {
switch (type) {
case "story":
return <StoryPage data={currentStepData} onClicked={handleNextStep}/>;
case "conversation":
return <div onClick={handleNextStep}>conversation</div>;
case "option":
return <div onClick={handleNextStep}>option</div>;
default:
return <LoadingScene />;
}
};
return (
<div>
{renderComponent(currentStepData.type)}
</div>
);
}
export default VitualNovelHandler;