ed
This commit is contained in:
parent
510e3ffcf2
commit
f43cf424cf
305 changed files with 34683 additions and 0 deletions
82
resources/[carscripts]/community_bridge/web/src/dialogue.css
Normal file
82
resources/[carscripts]/community_bridge/web/src/dialogue.css
Normal file
|
@ -0,0 +1,82 @@
|
|||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.dialogue-container {
|
||||
position: fixed;
|
||||
bottom: 30px;
|
||||
width: 50%;
|
||||
background: transparent;
|
||||
padding: 25px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.dialogue-text {
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
padding: 20px;
|
||||
border-radius: 4px;
|
||||
margin: 15px 0;
|
||||
line-height: 1.6;
|
||||
font-size: 1.1em;
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.dialogue-options {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.dialogue-button {
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
color: white;
|
||||
padding: 12px 24px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
font-size: 0.95em;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
min-width: calc(33.333% - 8px);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.dialogue-button:hover {
|
||||
background: rgba(51, 51, 51, 0.55);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #ffffff;
|
||||
margin: 0;
|
||||
font-size: 1.4em;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
p {
|
||||
color: #fff;
|
||||
margin: 0;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* Add this for better text rendering */
|
||||
* {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
54
resources/[carscripts]/community_bridge/web/src/dialogue.jsx
Normal file
54
resources/[carscripts]/community_bridge/web/src/dialogue.jsx
Normal file
|
@ -0,0 +1,54 @@
|
|||
import { useState } from 'react'
|
||||
import { fetchNui } from './fetch'
|
||||
import './dialogue.css'
|
||||
|
||||
function Dialogue() {
|
||||
const [count, setCount] = useState(0)
|
||||
const [dialogueOptions, setDialogueOption] = useState([])
|
||||
const [currentText, setCurrentText] = useState("Welcome traveler! How can I help you today?")
|
||||
const [speakerName, setSpeakerName] = useState("Friendly NPC")
|
||||
|
||||
const handleMessage = (event) => {
|
||||
var data = event.data;
|
||||
|
||||
if (data !== undefined && data.type === "close") {
|
||||
document.getElementById('root').classList.add("hidden");
|
||||
}
|
||||
if (data !== undefined && data.type === "open") {
|
||||
setDialogueOption(data.options);
|
||||
setCurrentText(data.text);
|
||||
setSpeakerName(data.name);
|
||||
document.getElementById('root').classList.remove("hidden");
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("message", handleMessage);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="container">
|
||||
{/* Dialogue System */}
|
||||
<div className="dialogue-container">
|
||||
<h2>{speakerName}</h2>
|
||||
<div className="dialogue-text">
|
||||
<p>{currentText}</p>
|
||||
</div>
|
||||
<div className="dialogue-options">
|
||||
{dialogueOptions.map((option) => (
|
||||
<button
|
||||
key={option.id}
|
||||
onClick={() => fetchNui("dialogue:SelectOption", { name: speakerName, id: option.id })}
|
||||
className="dialogue-button"
|
||||
>
|
||||
{option.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Dialogue
|
26
resources/[carscripts]/community_bridge/web/src/fetch.jsx
Normal file
26
resources/[carscripts]/community_bridge/web/src/fetch.jsx
Normal file
|
@ -0,0 +1,26 @@
|
|||
export const fetchNui = async (cbName, data = {}) => {
|
||||
const options = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=UTF-8',
|
||||
},
|
||||
body: JSON.stringify(data)
|
||||
};
|
||||
|
||||
try {
|
||||
const resourceName = window.GetParentResourceName?.() || '';
|
||||
const resp = await fetch(`https://${resourceName}/${cbName}`, options);
|
||||
|
||||
if (!resp.ok) {
|
||||
throw new Error(`HTTP error! status: ${resp.status}`);
|
||||
}
|
||||
|
||||
return await resp.json();
|
||||
} catch (error) {
|
||||
console.error(`Fetch error for ${cbName}:`, error);
|
||||
if (!window.GetParentResourceName?.()) {
|
||||
console.error('Resource name is null - are you testing in browser?');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
.hidden {
|
||||
display: none;
|
||||
|
||||
}
|
||||
|
||||
* {
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import Dialogue from './dialogue';
|
||||
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<Dialogue />
|
||||
</React.StrictMode>
|
||||
);
|
14
resources/[carscripts]/community_bridge/web/src/main.jsx
Normal file
14
resources/[carscripts]/community_bridge/web/src/main.jsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom/client'
|
||||
import Dialogue from './dialogue.jsx'
|
||||
import './index.css'
|
||||
|
||||
const root = document.getElementById('root')
|
||||
ReactDOM.createRoot(root).render(
|
||||
<React.StrictMode>
|
||||
<Dialogue />
|
||||
</React.StrictMode>,
|
||||
)
|
||||
|
||||
// add hidden to root element
|
||||
root.classList.add('hidden')
|
0
resources/[carscripts]/community_bridge/web/src/nui
Normal file
0
resources/[carscripts]/community_bridge/web/src/nui
Normal file
3
resources/[carscripts]/community_bridge/web/src/test.css
Normal file
3
resources/[carscripts]/community_bridge/web/src/test.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
.hidden {
|
||||
display: none;
|
||||
}
|
32
resources/[carscripts]/community_bridge/web/src/test.jsx
Normal file
32
resources/[carscripts]/community_bridge/web/src/test.jsx
Normal file
|
@ -0,0 +1,32 @@
|
|||
import { useState } from 'react'
|
||||
import './test.css'
|
||||
|
||||
function Dialogue() {
|
||||
const [count, setCount] = useState(0)
|
||||
|
||||
const handleMessage = (event) => {
|
||||
var data = event.data;
|
||||
|
||||
if (data !== undefined && data.type === "hide") {
|
||||
document.getElementById('root').classList.add("hidden");
|
||||
}
|
||||
if (data !== undefined && data.type === "open") {
|
||||
document.getElementById('root').classList.remove("hidden");
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("message", handleMessage);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="container">
|
||||
<img src= "https://dunb17ur4ymx4.cloudfront.net/wysiwyg/1364588/7b504ad7f496249800123e36ecfb3905677e337d.png"></img>
|
||||
<br></br>
|
||||
<button onClick={() => setCount(count + 1)}>Click me</button>
|
||||
<p>You clicked {count} times</p>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Dialogue
|
Loading…
Add table
Add a link
Reference in a new issue