Esempi di schermate dell'UI
Tutti gli esempi sono stati creati utilizzando elementi HTML di base; per migliorare la grafica, sarà necessario sostituirli con componenti UI dalla propria libreria preferita.
Schermata dell'UI del dialogo narrativo
Ad esempio:
import { useQueryDialogue } from "../hooks/useQueryInterface";
import ChoiceMenu from "./ChoiceMenu";
export default function NarrationScreen() {
const { data: { text, character } = {} } = useQueryDialogue();
return (
<div
style={{
position: "absolute",
display: "flex",
flexDirection: "column",
height: "100%",
width: "100%",
}}
>
<div style={{ flex: 1, minHeight: 0 }}>
{/* READ THIS: https://pixi-vn.web.app/start/choices.html#how-to-create-the-choice-menu-ui-screen */}
<ChoiceMenu />
</div>
{text && (
<div
style={{
flex: "0 0 auto",
height: "30%",
minHeight: 0,
pointerEvents: "auto",
backgroundColor: "white",
display: "flex",
flexDirection: "column",
overflow: "hidden",
}}
>
{character && character.name && <b>{`${character?.name || ""} ${character?.surname || ""}`}</b>}
<div
style={{
display: "flex",
flexDirection: "row",
height: "100%",
minHeight: 0,
overflow: "hidden",
}}
>
{character?.icon && (
<img
src={character?.icon}
loading='lazy'
alt=''
style={{
maxWidth: "30%",
height: "auto",
objectFit: "contain",
display: "block",
}}
/>
)}
<div style={{ flex: 1, minHeight: 0, overflow: "auto", height: "100%" }}>{text}</div>
</div>
</div>
)}
</div>
);
}
Schermata dell'UI del menu di scelta
Ad esempio:
import useNarrationFunctions from "../hooks/useNarrationFunctions";
import { useQueryChoiceMenuOptions } from "../hooks/useQueryInterface";
export default function ChoiceMenu() {
const { data: menu = [] } = useQueryChoiceMenuOptions();
const { selectChoice } = useNarrationFunctions();
return (
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "center",
width: "100%",
height: "100%",
overflow: "auto",
gap: "8px",
maxHeight: "100%",
margin: 0,
pointerEvents: menu?.length > 0 ? "auto" : "none",
}}
>
{menu?.map((item, index) => (
<button
key={"choice-" + index}
style={{
justifyContent: "center",
alignItems: "center",
}}
onClick={() => selectChoice(item)}
>
{item.text}
</button>
))}
</div>
);
}
Go next button
Ad esempio:
import { useState } from "react";
import useNarrationFunctions from "../hooks/useNarrationFunctions";
import { useQueryCanGoNext } from "../hooks/useQueryInterface";
export default function NextButton() {
const { data: canGoNext = false } = useQueryCanGoNext();
const [loading, setLoading] = useState(false);
const { goNext } = useNarrationFunctions();
if (!canGoNext) {
return null;
}
return (
<button
onClick={() => {
setLoading(true);
goNext()
.then(() => setLoading(false))
.catch(() => setLoading(false));
}}
disabled={loading}
style={{
width: 40,
height: 20,
pointerEvents: "auto",
}}
>
Next
</button>
);
}
Go back button
Ad esempio:
import { useState } from "react";
import useNarrationFunctions from "../hooks/useNarrationFunctions";
import { useQueryCanGoBack } from "../hooks/useQueryInterface";
export default function BackButton() {
const { data: canGoBack = false } = useQueryCanGoBack();
const [loading, setLoading] = useState(false);
const { goBack } = useNarrationFunctions();
if (!canGoBack) {
return null;
}
return (
<button
onClick={() => {
setLoading(true);
goBack()
.then(() => setLoading(false))
.catch(() => setLoading(false));
}}
disabled={loading}
style={{
width: 40,
height: 20,
pointerEvents: "auto",
}}
>
Back
</button>
);
}
Input prompt dialog UI
Ad esempio:
import { narration } from "@drincs/pixi-vn";
import { useQueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { INTERFACE_DATA_USE_QUEY_KEY, useQueryDialogue, useQueryInputValue } from "../../hooks/useQueryInterface";
export default function TextInput() {
const { data: { text } = {} } = useQueryDialogue();
const {
data: { isRequired: open, currentValue } = {
currentValue: undefined,
isRequired: false,
},
} = useQueryInputValue<string | number>();
const [tempValue, setTempValue] = useState<string | number>();
const queryClient = useQueryClient();
return (
<dialog
open={open}
style={{
pointerEvents: "auto",
}}
>
<p>{text}</p>
{open && (
<input
defaultValue={currentValue || ""}
onChange={(e) => {
if (e && e.target && "value" in e.target) {
let value: any = e.target.value;
if ("type" in e.target && e.target.type === "number" && "valueAsNumber" in e.target) {
value = e.target.valueAsNumber;
}
setTempValue(value);
}
}}
/>
)}
<button
onClick={() => {
narration.inputValue = tempValue || currentValue;
setTempValue(undefined);
queryClient.invalidateQueries({
queryKey: [INTERFACE_DATA_USE_QUEY_KEY],
});
}}
>
Confirm
</button>
</dialog>
);
}
History UI screen
Ad esempio:
import { Box, Stack } from "@mui/system";
import React from "react";
import { useQueryNarrativeHistory } from "../use_query/useQueryInterface";
export default function HistoryScreen() {
const { data = [] } = useQueryNarrativeHistory();
return (
<dialog
open={true}
style={{
height: "80%",
}}
>
<Box
sx={{
display: "flex",
flex: 1,
minHeight: 0,
px: 2,
py: 3,
overflowY: "scroll",
flexDirection: "column-reverse",
pointerEvents: "auto",
overflow: "auto",
height: "80%",
}}
>
<Stack spacing={2} justifyContent="flex-end">
{data.map((data, index) => {
return (
<React.Fragment key={"history" + index}>
<Stack direction="row" spacing={1.5}>
<img
src={data.icon}
loading="lazy"
alt=""
style={{
verticalAlign: "middle",
maxWidth: "50px",
maxHeight: "50px",
borderRadius: "50%",
}}
/>
<Box sx={{ flex: 1 }}>
{data.character && data.character}
<div />
{data.text}
</Box>
</Stack>
<Stack direction="row" spacing={0.5}>
<Box sx={{ flex: 1 }}>
{data.choices &&
data.choices.map((choice, index) => {
if (choice.hidden) {
return null;
}
if (choice.isResponse) {
return (
<div
key={"choices-success" + index}
style={{
display: "inline-block",
padding: "5px 5px",
fontSize: "12px",
borderRadius: "25px",
backgroundColor: "#21ff3e",
}}
>
{choice.text}
</div>
);
}
return (
<div
key={"choices" + index}
style={{
display: "inline-block",
padding: "5px 5px",
fontSize: "12px",
borderRadius: "25px",
backgroundColor: "#bcfdff",
}}
>
{choice.text}
</div>
);
})}
{data.inputValue && (
<div
key={"choices-success" + index}
style={{
display: "inline-block",
padding: "5px 5px",
fontSize: "12px",
borderRadius: "25px",
backgroundColor: "#b0c2b2",
}}
>
{data.inputValue.toString()}
</div>
)}
</Box>
</Stack>
</React.Fragment>
);
})}
</Stack>
</Box>
</dialog>
);
}