Add CodeCard, adjust tooltips

This commit is contained in:
Corey 2024-05-12 02:13:13 +00:00
parent 9276118a37
commit b8ebc61213
8 changed files with 196 additions and 20 deletions

View File

@ -0,0 +1,128 @@
import { ContentCopy } from '@mui/icons-material';
import {
Card,
CardContent,
CardHeader,
IconButton,
Tooltip,
} from '@mui/material';
import { useEffect, useState } from 'react';
type CodeCardProps = {
title: string;
file?: string;
content?: string;
copy?: boolean;
};
export default function CodeCard({
title,
file,
content,
copy,
}: CodeCardProps) {
const [fileContent, setFileContent] = useState<string>('');
const [clipboardTooltip, setClipboardTooltip] = useState('Copy contents.');
const [clipboardTooltipOpen, setClipboardTooltipOpen] = useState(false);
const handleClipboardTooltipClose = () => {
setClipboardTooltipOpen(false);
};
const handleClipboardTooltipOpen = () => {
setClipboardTooltipOpen(true);
};
useEffect(() => {
if (file) {
fetch(file)
.then((response) => response.text())
.then((text) => setFileContent(text))
.catch((error) => setFileContent(error.toString()));
}
}, [file]);
const copyContentsToClipboard = async (text: string) => {
try {
navigator.clipboard.writeText(text);
setClipboardTooltip('Copied contents!');
handleClipboardTooltipOpen();
setTimeout(() => {
handleClipboardTooltipClose();
setClipboardTooltip('Copy contents.');
}, 3000);
} catch (error) {
handleClipboardTooltipOpen();
if (error instanceof Error) {
setClipboardTooltip(error.message);
} else {
setClipboardTooltip('Something went wrong!');
}
setTimeout(() => {
handleClipboardTooltipClose();
setClipboardTooltip('Copy contents.');
}, 3000);
}
};
return (
<Card raised className="m-1">
<CardHeader
disableTypography
title={title}
action={
copy &&
window.isSecureContext && (
<Tooltip
arrow
disableInteractive
title={clipboardTooltip}
open={
clipboardTooltip === 'Copied contents!' || clipboardTooltipOpen
}
onOpen={handleClipboardTooltipOpen}
onClose={handleClipboardTooltipClose}
>
<IconButton
// size="small"
// className="py-0"
onClick={(event) => {
event.stopPropagation();
copyContentsToClipboard(content || fileContent);
}}
disableRipple
>
<ContentCopy
sx={{
fontSize: (theme) => theme.typography.subtitle1.fontSize,
}}
/>
</IconButton>
</Tooltip>
)
}
className="py-0"
sx={{ backgroundColor: (theme) => theme.palette.background.paper }}
/>
<CardContent
className="px-2 py-0"
sx={{
backgroundColor: 'rgba(18, 18, 18, 0.12)',
}}
>
{file ? (
<pre className="m-0 select-text">
<code>{fileContent}</code>
</pre>
) : (
<pre className="m-0 select-text p-2">
<code>{content}</code>
</pre>
)}
</CardContent>
</Card>
);
}
CodeCard.defaultProps = {
file: '',
content: '',
copy: true,
};

View File

@ -631,7 +631,7 @@ export default function SearchServers({
alignItems="center"
>
<Box className="flex min-w-full justify-end pt-2">
<Tooltip title="Sort" arrow disableInteractive>
<Tooltip title="Sort" arrow disableInteractive placement="top">
<IconButton
// onClick={() => {
// setSearchState(SearchStateDefaults);
@ -640,7 +640,12 @@ export default function SearchServers({
<Sort />
</IconButton>
</Tooltip>
<Tooltip title="Reset filters." arrow disableInteractive>
<Tooltip
title="Reset filters."
arrow
disableInteractive
placement="top"
>
<IconButton
onClick={() => {
setSearchState(SearchStateDefaults);

View File

@ -1,10 +1,11 @@
import { AddCircle } from '@mui/icons-material';
import { AddCircleTwoTone } from '@mui/icons-material';
import {
Box,
IconButton,
ToggleButton,
ToggleButtonGroup,
Tooltip,
useTheme,
} from '@mui/material';
import { ServerData } from '../../data/ServerData';
@ -60,6 +61,7 @@ type ExpansionBarProps = { server: ServerData };
export default function ExpansionBar({ server }: ExpansionBarProps) {
const { expansions } = server;
const theme = useTheme();
const addons = ['acp', 'amk', 'asa', 'abyssea', 'voidwatch', 'rov', 'tvr'];
@ -101,9 +103,10 @@ export default function ExpansionBar({ server }: ExpansionBarProps) {
arrow
>
<IconButton className="p-0" disableRipple>
<AddCircle
<AddCircleTwoTone
style={{
maxHeight: '1rem',
color: theme.palette.text.primary,
}}
/>
</IconButton>

View File

@ -318,6 +318,7 @@ export default function ServerCard({ server, children }: ServerCardProps) {
title={`Server allows ${server.login_limit === 0 ? 'unlimited' : server.login_limit} simultaneous game sessions per IP.`}
arrow
disableInteractive
placement="top"
>
<img
src={CopyImageIcon}
@ -343,6 +344,7 @@ export default function ServerCard({ server, children }: ServerCardProps) {
}
arrow
disableInteractive
placement="top"
>
<IconButton
component={Link}

View File

@ -40,6 +40,7 @@ export default function SettingsChipCloud({ server }: SettingsChipCloudProps) {
arrow
disableInteractive
title={ServerSettingsInfo[key].description}
placement="top"
>
<Chip
label={`${ServerSettingsInfo[key].name === '' ? key : ServerSettingsInfo[key].name}`}

8
client/src/data/api.lua Normal file
View File

@ -0,0 +1,8 @@
xi = xi or {}
xi.settings = xi.settings or {}
xi.settings.api =
{
WEBSITE = '',
DO_NOT_TRACK = false,
}

View File

@ -10,11 +10,37 @@ import {
alpha,
} from '@mui/material';
import Link from '@mui/material/Link';
import CodeCard from '../components/CodeCard';
import { useThemeModeContext } from '../context/ThemeContext';
import apiLua from '../data/api.lua?raw';
export default function About() {
const { themeMode } = useThemeModeContext();
const recommendedSettings = `MAIN.SERVER_NAME
MAIN.MAX_LEVEL
LOGIN.LOGIN_LIMIT
LOGIN.CLIENT_VER
MAIN.ENABLE_TRUST_CASTING
MAP.LEVEL_SYNC_ENABLE
MAIN.HOMEPOINT_TELEPORT
MAIN.ENABLE_SURVIVAL_GUIDE
MAIN.ENABLE_FIELD_MANUALS
MAIN.ENABLE_GROUNDS_TOMES
MAIN.ENABLE_ROE
LOGIN.RISE_OF_ZILART
LOGIN.CHAINS_OF_PROMATHIA
LOGIN.TREASURES_OF_AHT_URGHAN
LOGIN.WINGS_OF_THE_GODDESS
LOGIN.SEEKERS_OF_ADOULIN
MAIN.ENABLE_ACP
MAIN.ENABLE_AMK
MAIN.ENABLE_ASA
MAIN.ENABLE_ABYSSEA
MAIN.ENABLE_VOIDWATCH
MAIN.ENABLE_ROV
MAIN.ENABLE_TVR`;
return (
<>
<Card className="mb-2" raised={themeMode === 'light'}>
@ -147,25 +173,28 @@ export default function About() {
>
Create a new file <b>settings/api.lua</b> in your server
directory.
<Card className="bg-neutral-500/50">
<pre className="m-0 select-text p-2">
<code>
{`xi = xi or {}
xi.settings = xi.settings or {}
xi.settings.api =
{
WEBSITE = '',
DO_NOT_TRACK = false,
}`}
</code>
</pre>
</Card>
<CodeCard title="api.lua" content={apiLua} />
The world server needs to be restarted after any changes to any
of the settings. If you set <b>DO_NOT_TRACK</b> to <b>true</b>,
your server will be removed on the next update.
</Typography>
</Box>
<Box className="mb-3">
<Typography align="center" variant="h6">
Which settings are used?
</Typography>
<Typography
component="span"
variant="body1"
color={(theme) => alpha(theme.palette.text.primary, 0.87)}
>
Anything that differs from the default LSB settings will be
displayed in the &quot;Settings Summary&quot; section for a
server. The following settings are always included as part of
the UI:
<CodeCard title="Settings" content={recommendedSettings} />
</Typography>
</Box>
</AccordionDetails>
</Accordion>
</Card>

View File

@ -16,8 +16,8 @@ export default defineConfig({
strictPort: true,
port: 3000,
hmr: {
//port: 3010,
host: 'localhost'
// port: 3010,
host: 'localhost',
},
},
test: {