forked from Simnation/Main
edit
This commit is contained in:
parent
be02d05ba8
commit
fc7ea910e9
35 changed files with 11992 additions and 1 deletions
73
resources/[tools]/mt_lib/web/src/components/Dialogue.tsx
Normal file
73
resources/[tools]/mt_lib/web/src/components/Dialogue.tsx
Normal file
|
@ -0,0 +1,73 @@
|
|||
import React, { useState, useRef } from "react"
|
||||
import { DEFAULT_THEME, Paper, Text, Divider, Stack, Button } from '@mantine/core'
|
||||
import { fetchNui } from "../utils/fetchNui"
|
||||
import { useNuiEvent } from "../hooks/useNuiEvent"
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import * as Icons from '@fortawesome/free-solid-svg-icons'
|
||||
import { IconProp } from '@fortawesome/fontawesome-svg-core'
|
||||
|
||||
const Dialogue: React.FC = () => {
|
||||
const theme = DEFAULT_THEME
|
||||
const [options, setOptions] = useState([])
|
||||
const [label, setLabel] = useState('')
|
||||
const [speech, setSpeech] = useState('')
|
||||
|
||||
useNuiEvent<any>('dialogue', (data) => {
|
||||
setOptions(data.options)
|
||||
setLabel(data.label)
|
||||
setSpeech(data.speech)
|
||||
})
|
||||
|
||||
const getIconByName = (iconName: string) => {
|
||||
const formattedName = `fa${iconName.charAt(0).toUpperCase() + iconName.slice(1).replace(/-./g, (m) => m[1].toUpperCase())}`
|
||||
return Icons[formattedName as keyof typeof Icons] || Icons.faQuestionCircle
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
margin: -8,
|
||||
position: 'fixed',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'flex-end',
|
||||
background: `linear-gradient(180deg, rgba(255, 255, 255, 0) 75%, rgba(0, 0, 0, 0.80) 100%)`
|
||||
}}
|
||||
>
|
||||
<Stack miw={500} maw={1000} m={50} spacing={5}>
|
||||
<Text size="xl" fw={700} color="white">{label}</Text>
|
||||
<Paper withBorder p={5} pl={10}>
|
||||
<Text color="white" size="lg" fw={500}>{speech}</Text>
|
||||
</Paper>
|
||||
<Divider />
|
||||
<div
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
flexWrap: 'wrap',
|
||||
gap: 10
|
||||
}}
|
||||
>
|
||||
{options.length > 0 && options.map(({ label, icon, id, close, canInteract }) => (
|
||||
canInteract && <Button
|
||||
color="gray"
|
||||
bg={theme.colors.dark[7]}
|
||||
leftIcon={<FontAwesomeIcon icon={getIconByName(icon) as IconProp} />}
|
||||
style={{
|
||||
border: `1px solid ${theme.colors.dark[4]}`
|
||||
}}
|
||||
onClick={() => fetchNui('executeAction', { id, options, close })}
|
||||
>
|
||||
{label}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</Stack>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Dialogue
|
|
@ -0,0 +1,62 @@
|
|||
import React, { useState } from "react"
|
||||
import { DEFAULT_THEME, Paper, Text, Divider, TypographyStylesProvider } from '@mantine/core'
|
||||
import { useNuiEvent } from "../hooks/useNuiEvent"
|
||||
|
||||
const MissionStatus: React.FC = () => {
|
||||
const theme = DEFAULT_THEME
|
||||
const [title, setTitle] = useState('')
|
||||
const [text, setText] = useState('')
|
||||
|
||||
useNuiEvent<any>('missionStatus', (data) => {
|
||||
setTitle(data.title)
|
||||
setText(data.text)
|
||||
})
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
margin: -8,
|
||||
position: 'fixed',
|
||||
display: 'flex',
|
||||
alignItems: 'center'
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
maxWidth: 400,
|
||||
position: 'absolute',
|
||||
left: 20,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
textAlign: 'center',
|
||||
gap: 5
|
||||
}}
|
||||
>
|
||||
<Text size="xl" color="white" fw={700}>{title}</Text>
|
||||
<Divider
|
||||
color="dark.0"
|
||||
size="lg"
|
||||
style={{
|
||||
borderRadius: theme.radius.md
|
||||
}}
|
||||
/>
|
||||
<Paper p={10} withBorder radius="sm">
|
||||
<TypographyStylesProvider
|
||||
style={{
|
||||
textAlign: 'left'
|
||||
}}
|
||||
>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: text }}
|
||||
/>
|
||||
</TypographyStylesProvider>
|
||||
</Paper>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MissionStatus
|
64
resources/[tools]/mt_lib/web/src/components/TextUI.tsx
Normal file
64
resources/[tools]/mt_lib/web/src/components/TextUI.tsx
Normal file
|
@ -0,0 +1,64 @@
|
|||
import React, { useState } from "react"
|
||||
import { DEFAULT_THEME, Paper, Text, Kbd } from '@mantine/core'
|
||||
import { useNuiEvent } from "../hooks/useNuiEvent"
|
||||
|
||||
const TextUI: React.FC = () => {
|
||||
const theme = DEFAULT_THEME
|
||||
const [key, setKey] = useState('')
|
||||
const [label, setLabel] = useState('')
|
||||
const [position, setPosition] = useState('')
|
||||
|
||||
useNuiEvent<any>('textUI', (data) => {
|
||||
setKey(data.key)
|
||||
setLabel(data.label)
|
||||
setPosition(data.position)
|
||||
})
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
margin: -8,
|
||||
position: 'fixed',
|
||||
display: 'flex',
|
||||
justifyContent: ((position == 'bottom' || position == 'top') ? 'center' : ''),
|
||||
alignItems: ((position == 'right' || position == 'left') ? 'center' : '')
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
maxWidth: 400,
|
||||
position: 'absolute',
|
||||
bottom: (position == 'bottom' ? 20 : 'auto'),
|
||||
top: (position == 'top' ? 20 : 'auto'),
|
||||
right: (position == 'right' ? 20 : 'auto'),
|
||||
left: (position == 'left' ? 20 : 'auto'),
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
textAlign: 'center',
|
||||
gap: 5
|
||||
}}
|
||||
>
|
||||
<Paper
|
||||
withBorder
|
||||
radius="sm"
|
||||
p={5}
|
||||
style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
alignItems: 'flex-start',
|
||||
gap: 5
|
||||
}}
|
||||
>
|
||||
<Kbd>{key}</Kbd>
|
||||
<Text fw={700}>{label}</Text>
|
||||
</Paper>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TextUI
|
74
resources/[tools]/mt_lib/web/src/components/Timer.tsx
Normal file
74
resources/[tools]/mt_lib/web/src/components/Timer.tsx
Normal file
|
@ -0,0 +1,74 @@
|
|||
import React, { useState, useEffect } from "react"
|
||||
import { DEFAULT_THEME, Paper, Text, Progress } from '@mantine/core'
|
||||
import { fetchNui } from "../utils/fetchNui"
|
||||
import { useNuiEvent } from "../hooks/useNuiEvent"
|
||||
|
||||
const Timer: React.FC = () => {
|
||||
const theme = DEFAULT_THEME
|
||||
const [time, setTime] = useState(0)
|
||||
const [maxTime, setMaxTime] = useState(60)
|
||||
const [position, setPosition] = useState('')
|
||||
const [label, setLabel] = useState('')
|
||||
|
||||
useNuiEvent<any>('timer', (data) => {
|
||||
setLabel(data.label)
|
||||
setTime(data.time)
|
||||
setMaxTime(data.time)
|
||||
setPosition(data.position)
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (time > 0) {
|
||||
const timerInterval = setInterval(() => {
|
||||
setTime((prevTime) => {
|
||||
if (prevTime <= 1) {
|
||||
clearInterval(timerInterval)
|
||||
fetchNui('finishTimer')
|
||||
return 0
|
||||
}
|
||||
return prevTime - 1
|
||||
})
|
||||
}, 1000)
|
||||
|
||||
return () => clearInterval(timerInterval)
|
||||
}
|
||||
}, [time])
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
margin: -8,
|
||||
position: 'fixed',
|
||||
display: 'flex',
|
||||
justifyContent: ((position == 'bottom' || position == 'top') ? 'center' : ''),
|
||||
alignItems: ((position == 'right' || position == 'left') ? 'center' : '')
|
||||
}}
|
||||
>
|
||||
<Paper
|
||||
withBorder
|
||||
radius="sm"
|
||||
p={10}
|
||||
style={{
|
||||
maxWidth: 400,
|
||||
position: 'absolute',
|
||||
bottom: (position == 'bottom' ? 20 : 'auto'),
|
||||
top: (position == 'top' ? 20 : 'auto'),
|
||||
right: (position == 'right' ? 20 : 'auto'),
|
||||
left: (position == 'left' ? 20 : 'auto'),
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center',
|
||||
textAlign: 'center',
|
||||
gap: 5
|
||||
}}
|
||||
>
|
||||
<Text fw={700}>{label}: {time}s</Text>
|
||||
<Progress w="100%" value={(time / maxTime) * 100} />
|
||||
</Paper>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Timer
|
Loading…
Add table
Add a link
Reference in a new issue