discord-embed-visualizer
Version:
<div align="center">
838 lines (823 loc) • 46.7 kB
JavaScript
import { jsx, jsxs } from 'react/jsx-runtime';
import debounce from 'debounce';
import { ColorPicker } from 'mui-color';
import PropTypes from 'prop-types';
import { useState, useEffect } from 'react';
import ReactMarkdown from 'react-markdown';
import { Prism } from 'react-syntax-highlighter';
import gfm from 'remark-gfm';
import DeleteForeverIcon from '@mui/icons-material/DeleteForever';
import ExpandLessIcon from '@mui/icons-material/ExpandLess';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { DateTimePicker } from '@mui/lab';
import DateFnsUtils from '@mui/lab/AdapterDateFns';
import LocalizationProvider from '@mui/lab/LocalizationProvider';
import Button from '@mui/material/Button/Button';
import green from '@mui/material/colors/green';
import Dialog from '@mui/material/Dialog/Dialog';
import DialogActions from '@mui/material/DialogActions/DialogActions';
import DialogContent from '@mui/material/DialogContent/DialogContent';
import DialogContentText from '@mui/material/DialogContentText/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle/DialogTitle';
import FormControlLabel from '@mui/material/FormControlLabel/FormControlLabel';
import Grid from '@mui/material/Grid/Grid';
import IconButton from '@mui/material/IconButton/IconButton';
import MenuItem from '@mui/material/MenuItem/MenuItem';
import Select from '@mui/material/Select/Select';
import { StyledEngineProvider } from '@mui/material/styles';
import ThemeProvider from '@mui/material/styles/ThemeProvider';
import Switch from '@mui/material/Switch/Switch';
import TextField from '@mui/material/TextField/TextField';
import Tooltip from '@mui/material/Tooltip/Tooltip';
import Typography from '@mui/material/Typography/Typography';
import { withStyles, makeStyles } from '@mui/styles';
import createTheme from '@mui/material/styles/createTheme';
import { Accordion as Accordion$1, AccordionSummary as AccordionSummary$1, AccordionDetails as AccordionDetails$1 } from '@mui/material';
import { format } from 'date-fns';
import Link from '@mui/material/Link/Link';
import Paper from '@mui/material/Paper/Paper';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
var materialDark = {
"code[class*=\"language-\"]": {
"textAlign": "left",
"whiteSpace": "pre",
"wordSpacing": "normal",
"wordBreak": "normal",
"wordWrap": "normal",
"color": "#eee",
"background": "#2f2f2f",
"fontFamily": "Roboto Mono, monospace",
"fontSize": "1em",
"lineHeight": "1.5em",
"MozTabSize": "4",
"OTabSize": "4",
"tabSize": "4",
"WebkitHyphens": "none",
"MozHyphens": "none",
"msHyphens": "none",
"hyphens": "none"
},
"pre[class*=\"language-\"]": {
"textAlign": "left",
"whiteSpace": "pre",
"wordSpacing": "normal",
"wordBreak": "normal",
"wordWrap": "normal",
"color": "#eee",
"background": "#2f2f2f",
"fontFamily": "Roboto Mono, monospace",
"fontSize": "1em",
"lineHeight": "1.5em",
"MozTabSize": "4",
"OTabSize": "4",
"tabSize": "4",
"WebkitHyphens": "none",
"MozHyphens": "none",
"msHyphens": "none",
"hyphens": "none",
"overflow": "auto",
"position": "relative",
"margin": "0.5em 0",
"padding": "1.25em 1em"
},
"code[class*=\"language-\"]::-moz-selection": {
"background": "#363636"
},
"pre[class*=\"language-\"]::-moz-selection": {
"background": "#363636"
},
"code[class*=\"language-\"] ::-moz-selection": {
"background": "#363636"
},
"pre[class*=\"language-\"] ::-moz-selection": {
"background": "#363636"
},
"code[class*=\"language-\"]::selection": {
"background": "#363636"
},
"pre[class*=\"language-\"]::selection": {
"background": "#363636"
},
"code[class*=\"language-\"] ::selection": {
"background": "#363636"
},
"pre[class*=\"language-\"] ::selection": {
"background": "#363636"
},
":not(pre) > code[class*=\"language-\"]": {
"whiteSpace": "normal",
"borderRadius": "0.2em",
"padding": "0.1em"
},
".language-css > code": {
"color": "#fd9170"
},
".language-sass > code": {
"color": "#fd9170"
},
".language-scss > code": {
"color": "#fd9170"
},
"[class*=\"language-\"] .namespace": {
"Opacity": "0.7"
},
"atrule": {
"color": "#c792ea"
},
"attr-name": {
"color": "#ffcb6b"
},
"attr-value": {
"color": "#a5e844"
},
"attribute": {
"color": "#a5e844"
},
"boolean": {
"color": "#c792ea"
},
"builtin": {
"color": "#ffcb6b"
},
"cdata": {
"color": "#80cbc4"
},
"char": {
"color": "#80cbc4"
},
"class": {
"color": "#ffcb6b"
},
"class-name": {
"color": "#f2ff00"
},
"comment": {
"color": "#616161"
},
"constant": {
"color": "#c792ea"
},
"deleted": {
"color": "#ff6666"
},
"doctype": {
"color": "#616161"
},
"entity": {
"color": "#ff6666"
},
"function": {
"color": "#c792ea"
},
"hexcode": {
"color": "#f2ff00"
},
"id": {
"color": "#c792ea",
"fontWeight": "bold"
},
"important": {
"color": "#c792ea",
"fontWeight": "bold"
},
"inserted": {
"color": "#80cbc4"
},
"keyword": {
"color": "#c792ea"
},
"number": {
"color": "#fd9170"
},
"operator": {
"color": "#89ddff"
},
"prolog": {
"color": "#616161"
},
"property": {
"color": "#80cbc4"
},
"pseudo-class": {
"color": "#a5e844"
},
"pseudo-element": {
"color": "#a5e844"
},
"punctuation": {
"color": "#89ddff"
},
"regex": {
"color": "#f2ff00"
},
"selector": {
"color": "#ff6666"
},
"string": {
"color": "#a5e844"
},
"symbol": {
"color": "#c792ea"
},
"tag": {
"color": "#ff6666"
},
"unit": {
"color": "#fd9170"
},
"url": {
"color": "#ff6666"
},
"variable": {
"color": "#ff6666"
}
};
const theme = createTheme({
palette: {
mode: 'dark',
},
typography: {
fontFamily: [
'"Helvetica Neue"',
'Helvetica',
'Arial',
'sans-serif',
].join(','),
},
components: {
MuiTextField: {
defaultProps: {
variant: 'standard',
},
},
MuiButton: {
styleOverrides: {
containedPrimary: {
backgroundColor: 'rgb(114, 137, 218)',
borderColor: 'rgb(114, 137, 218)',
color: 'rgb(255, 255, 255)',
'&:hover': {
backgroundColor: 'rgb(142, 160, 225)',
borderColor: 'rgb(142, 160, 225)',
},
},
},
},
},
});
const Accordion = withStyles({
root: {
border: '1px solid rgba(0, 0, 0, .125)',
boxShadow: 'none',
'&:not(:last-child)': {
borderBottom: 0,
},
'&:before': {
display: 'none',
},
'&$expanded': {
margin: 'auto',
},
background: '#2f3136',
},
expanded: {},
})(Accordion$1);
const AccordionSummary = withStyles({
root: {
backgroundColor: 'rgba(0, 0, 0, .15)',
borderBottom: '1px solid rgba(0, 0, 0, .125)',
marginBottom: -1,
minHeight: 56,
'&$expanded': {
minHeight: 56,
},
},
content: {
'&$expanded': {
margin: '12px 0',
},
},
expanded: {},
})(AccordionSummary$1);
const AccordionDetails = withStyles(theme => ({
root: {
padding: theme.spacing(2),
},
}))(AccordionDetails$1);
const generateExport = (exporter, data) => {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
switch (exporter) {
case 'discordjs':
default:
return {
title: (_a = data.body) === null || _a === void 0 ? void 0 : _a.title,
type: 'rich',
description: (_b = data.body) === null || _b === void 0 ? void 0 : _b.description,
url: (_c = data.body) === null || _c === void 0 ? void 0 : _c.url,
timestamp: new Date(((_d = data.footer) === null || _d === void 0 ? void 0 : _d.timestamp) || new Date()).toISOString(),
color: data.color != null ? Number(`0x${data.color.charAt(0) === '#' ? data.color.slice(1) : data.color}`) : Number('0xfff'),
footer: {
text: (_e = data.footer) === null || _e === void 0 ? void 0 : _e.text,
icon_url: (_f = data.footer) === null || _f === void 0 ? void 0 : _f.iconUrl,
},
image: {
url: (_g = data.image) === null || _g === void 0 ? void 0 : _g.url,
height: ((_h = data.image) === null || _h === void 0 ? void 0 : _h.height) > 0 ? (_j = data.image) === null || _j === void 0 ? void 0 : _j.height : undefined,
width: ((_k = data.image) === null || _k === void 0 ? void 0 : _k.height) > 0 ? (_l = data.image) === null || _l === void 0 ? void 0 : _l.width : undefined,
},
thumbnail: {
url: (_m = data.image) === null || _m === void 0 ? void 0 : _m.url,
height: ((_o = data.image) === null || _o === void 0 ? void 0 : _o.height) > 0 ? (_p = data.image) === null || _p === void 0 ? void 0 : _p.height : undefined,
width: ((_q = data.image) === null || _q === void 0 ? void 0 : _q.height) > 0 ? (_r = data.image) === null || _r === void 0 ? void 0 : _r.width : undefined,
},
author: {
name: (_s = data.author) === null || _s === void 0 ? void 0 : _s.name,
url: (_t = data.author) === null || _t === void 0 ? void 0 : _t.url,
icon_url: (_u = data.author) === null || _u === void 0 ? void 0 : _u.iconUrl,
},
fields: data.fields,
};
}
};
const copyToClipBoard = function (str, callback) {
return __awaiter(this, void 0, void 0, function* () {
return navigator.permissions.query({ name: 'clipboard-write' })
.then((res) => __awaiter(this, void 0, void 0, function* () {
if (res.state === 'granted' || res.state === 'prompt') {
return navigator.clipboard.writeText(str)
.then(() => callback())
.catch(err => console.error('Failed to write to clipboard', err));
}
}));
});
};
const styles = makeStyles((theme) => ({
buttonGroup: {
position: 'absolute',
right: 60,
paddingRight: 8,
top: 4,
},
controlPadding: {
paddingTop: `${theme.spacing(2)} !important`,
},
fieldRoot: {
paddingBottom: theme.spacing(2),
},
exportField: {
userSelect: 'none',
margin: '-8px 0 -12px 0',
'& > div::before': {
display: 'none',
},
'& > pre': {
overflow: 'hidden !important',
},
},
}));
const matDark = materialDark;
const renderers = {
code: (_a) => {
var { node, inline, className, children } = _a, props = __rest(_a, ["node", "inline", "className", "children"]);
return jsx(Prism, Object.assign({ children: String(children).replace(/\n$/, ''), language: "json", PreTag: "div", style: matDark }, props));
},
};
function setEmbedDefaults(incoming) {
return {
author: {
name: incoming.author != null && incoming.author.name != null ? incoming.author.name : '',
iconUrl: incoming.author != null && incoming.author.iconUrl != null ? incoming.author.iconUrl : '',
url: incoming.author != null && incoming.author.url != null ? incoming.author.url : '',
},
color: incoming.color != null && incoming.color != null ? incoming.color : '#fff',
description: incoming.description != null ? incoming.description : '',
fields: incoming.fields != null ? incoming.fields : [],
footer: {
iconUrl: incoming.footer != null && incoming.footer.iconUrl != null ? incoming.footer.iconUrl : '',
text: incoming.footer != null && incoming.footer.text != null ? incoming.footer.text : '',
},
image: {
url: incoming.image != null && incoming.image.url != null ? incoming.image.url : '',
width: incoming.image != null && incoming.image.url != null ? incoming.image.width : 0,
height: incoming.image != null && incoming.image.url != null ? incoming.image.height : 0,
},
thumbnail: {
url: incoming.thumbnail != null && incoming.thumbnail.url != null ? incoming.thumbnail.url : '',
width: incoming.thumbnail != null && incoming.thumbnail.url != null ? incoming.thumbnail.width : 0,
height: incoming.thumbnail != null && incoming.thumbnail.url != null ? incoming.thumbnail.height : 0,
},
timestamp: incoming.timestamp != null ? incoming.timestamp : undefined,
title: incoming.title != null ? incoming.title : '',
url: incoming.url != null ? incoming.url : '',
};
}
function setFieldDefaults(incoming) {
var _a, _b, _c, _d, _e;
return {
author: (_a = incoming === null || incoming === void 0 ? void 0 : incoming.author) !== null && _a !== void 0 ? _a : false,
body: (_b = incoming === null || incoming === void 0 ? void 0 : incoming.body) !== null && _b !== void 0 ? _b : false,
fields: (_c = incoming === null || incoming === void 0 ? void 0 : incoming.fields) !== null && _c !== void 0 ? _c : false,
images: (_d = incoming === null || incoming === void 0 ? void 0 : incoming.images) !== null && _d !== void 0 ? _d : false,
footer: (_e = incoming === null || incoming === void 0 ? void 0 : incoming.footer) !== null && _e !== void 0 ? _e : false,
};
}
function Generator(props) {
var _a, _b, _c, _d;
const { defaultValue, hideFields, showExportSection, onChange } = props;
const defaultWithSet = setEmbedDefaults(defaultValue);
const shouldHideFields = setFieldDefaults(hideFields);
const [expanded, setExpanded] = useState(false);
const [fieldExpanded, setFieldExpanded] = useState(false);
const [author, setAuthor] = useState(Object.assign({}, defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.author));
const [color, setColor] = useState(defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.color);
const [description, setDescription] = useState(defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.description);
const [fields, setFields] = useState(defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.fields);
const [footer, setFooter] = useState(Object.assign({}, defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.footer));
const [image, setImage] = useState(Object.assign({}, defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.image));
const [thumbnail, setThumbnail] = useState(Object.assign({}, defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.thumbnail));
const [timestamp, setTimestamp] = useState(defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.timestamp);
const [title, setTitle] = useState(defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.title);
const [url, setUrl] = useState(defaultWithSet === null || defaultWithSet === void 0 ? void 0 : defaultWithSet.url);
const [copied, setCopied] = useState(false);
const [showExport, setShowExport] = useState(false);
const [exporter, setExporter] = useState('discordjs');
const classes = styles();
const handleAccordian = (panel) => (_evnt, isExpanded) => setExpanded(isExpanded ? panel : false);
const handleFieldAccordian = (panel) => (_evnt, isExpanded) => setFieldExpanded(isExpanded ? panel : false);
const handleFieldAdd = () => {
if (fields.length > 24) {
return;
}
setFields(preValues => [...preValues, { name: '', value: '', inline: false }]);
};
const handleFieldDelete = (index) => {
const fieldsClone = [...fields];
fieldsClone.splice(index, 1);
setFields(fieldsClone);
};
const handleFieldMove = (index, direction) => {
const fieldsClone = [...fields];
const toMove = Object.assign({}, fieldsClone[index]);
const toReplace = Object.assign({}, fieldsClone[direction === 'up' ? index - 1 : index + 1]);
fieldsClone[index] = toReplace;
fieldsClone[direction === 'up' ? index - 1 : index + 1] = toMove;
setFields(fieldsClone);
};
const exportedData = generateExport(exporter, { author, color, description, fields, footer, image, thumbnail, timestamp, title, url });
const handleExport = () => setShowExport(true);
const sendChanges = debounce(onChange, 300);
useEffect(() => {
let isLoaded = true;
if (isLoaded && onChange != null) {
sendChanges({ author, color, description, fields, footer, image, thumbnail, timestamp, title, url });
}
return () => {
isLoaded = false;
};
}, [author, color, description, fields, footer, image, thumbnail, timestamp, title, url]);
useEffect(() => {
const timer = setTimeout(() => {
setCopied(false);
}, 3000);
return () => clearTimeout(timer);
}, [copied]);
return (jsx(ThemeProvider, Object.assign({ theme: theme }, { children: jsx(StyledEngineProvider, Object.assign({ injectFirst: true }, { children: jsx(LocalizationProvider, Object.assign({ dateAdapter: DateFnsUtils }, { children: jsxs("div", { children: [jsxs(Dialog, Object.assign({ open: showExport, onClose: (_, reason) => reason !== 'backdropClick' ? setShowExport(false) : undefined, disableEscapeKeyDown: true, maxWidth: "md", fullWidth: true }, { children: [jsxs(DialogTitle, { children: [exporter, " Embed Data"] }), jsx(DialogContent, Object.assign({ dividers: true, style: { padding: 'unset' } }, { children: jsx(DialogContentText, Object.assign({ component: "div" }, { children: jsx(ReactMarkdown, Object.assign({ components: renderers, remarkPlugins: [gfm], className: classes.exportField }, { children: '```json\n' +
JSON.stringify(exportedData, null, 2)
+ '\n```' })) })) })), jsxs(DialogActions, { children: [jsx(Button, Object.assign({ autoFocus: true, variant: "contained", onClick: () => setShowExport(false) }, { children: "Close" })), jsx(Button, Object.assign({ color: "primary", style: { backgroundColor: copied && green[500] }, variant: "contained", onClick: () => copyToClipBoard(JSON.stringify(exportedData), () => setCopied(true)) }, { children: !copied ? 'Copy To Clipboard' : 'Copied!' }))] })] })), shouldHideFields['author'] === false && (jsxs(Accordion, Object.assign({ expanded: expanded === 'author', onChange: handleAccordian('author') }, { children: [jsx(AccordionSummary, Object.assign({ expandIcon: jsx(ExpandMoreIcon, {}) }, { children: jsx(Typography, Object.assign({ variant: "h5" }, { children: "Author" })) })), jsx(AccordionDetails, { children: jsxs(Grid, Object.assign({ container: true, spacing: 2 }, { children: [jsx(Grid, Object.assign({ item: true, xs: 12 }, { children: jsx(TextField, { value: author.name, onChange: evnt => setAuthor(preValues => { return Object.assign(Object.assign({}, preValues), { name: String(evnt.target.value) }); }), label: `Author ${((_a = author.name) === null || _a === void 0 ? void 0 : _a.length) || 0}/256`, fullWidth: true, error: (((_b = author.name) === null || _b === void 0 ? void 0 : _b.length) || 0) >= 256 }) })), jsx(Grid, Object.assign({ item: true, xs: 6 }, { children: jsx(TextField, { value: author.url, onChange: evnt => setAuthor(preValues => { return Object.assign(Object.assign({}, preValues), { url: String(evnt.target.value) }); }), label: "Author URL", helperText: "Can be a link to your social media or personal website.", fullWidth: true }) })), jsx(Grid, Object.assign({ item: true, xs: 6 }, { children: jsx(TextField, { value: author.iconUrl, onChange: evnt => setAuthor(preValues => { return Object.assign(Object.assign({}, preValues), { iconUrl: String(evnt.target.value) }); }), label: "Author Icon URL", helperText: "Full path to an image hosted online.", fullWidth: true }) }))] })) })] }))), shouldHideFields['body'] === false && (jsxs(Accordion, Object.assign({ expanded: expanded === 'body', onChange: handleAccordian('body') }, { children: [jsx(AccordionSummary, Object.assign({ expandIcon: jsx(ExpandMoreIcon, {}) }, { children: jsx(Typography, Object.assign({ variant: "h5" }, { children: "Body" })) })), jsx(AccordionDetails, { children: jsxs(Grid, Object.assign({ container: true, spacing: 2 }, { children: [jsx(Grid, Object.assign({ item: true, xs: 12 }, { children: jsx(TextField, { value: title, onChange: evnt => setTitle(String(evnt.target.value)), label: `Title ${(title === null || title === void 0 ? void 0 : title.length) || 0}/256`, fullWidth: true, error: ((title === null || title === void 0 ? void 0 : title.length) || 0) >= 256 }) })), jsx(Grid, Object.assign({ item: true, xs: 12 }, { children: jsx(TextField, { value: description, onChange: evnt => setDescription(String(evnt.target.value)), label: `Description ${(description === null || description === void 0 ? void 0 : description.length) || 0}/2048`, helperText: "Supports Discord Markdown Formatting", fullWidth: true, error: ((description === null || description === void 0 ? void 0 : description.length) || 0) >= 2048, multiline: true, rows: 6 }) })), jsx(Grid, Object.assign({ item: true, xs: 6 }, { children: jsx(TextField, { value: url, onChange: evnt => setUrl(String(evnt.target.value)), label: "URL", helperText: "This will make the title clickable.", fullWidth: true }) })), jsx(Grid, Object.assign({ item: true, xs: 6 }, { children: jsx(FormControlLabel, { control: jsx(ColorPicker, { value: color, onChange: (newColor) => setColor(String(newColor.hex)), deferred: true }), label: "Colour:", labelPlacement: "start", className: classes.controlPadding }) }))] })) })] }))), shouldHideFields['fields'] === false && (jsxs(Accordion, Object.assign({ expanded: expanded === 'fields', onChange: handleAccordian('fields') }, { children: [jsx(AccordionSummary, Object.assign({ expandIcon: jsx(ExpandMoreIcon, {}) }, { children: jsx(Typography, Object.assign({ variant: "h5" }, { children: "Fields" })) })), jsxs(AccordionDetails, { children: [jsx(Grid, Object.assign({ container: true, className: classes.fieldRoot }, { children: jsx(Grid, Object.assign({ item: true, xs: 12 }, { children: fields != null && fields.map((field, index) => (jsxs(Accordion, Object.assign({ expanded: fieldExpanded === `field-${index}`, onChange: handleFieldAccordian(`field-${index}`) }, { children: [jsxs(AccordionSummary, Object.assign({ expandIcon: jsx(ExpandMoreIcon, {}) }, { children: [jsxs(Typography, Object.assign({ variant: "body1" }, { children: ["Field ", index + 1, " -- ", field.name] })), jsxs("div", Object.assign({ className: classes.buttonGroup }, { children: [index !== 0 && (jsx(IconButton, Object.assign({ onClick: evnt => {
evnt.stopPropagation();
handleFieldMove(index, 'up');
}, onFocus: evnt => evnt.stopPropagation() }, { children: jsx(Tooltip, Object.assign({ title: "Move Up" }, { children: jsx(ExpandLessIcon, {}) })) }))), index !== fields.length - 1 && (jsx(IconButton, Object.assign({ onClick: evnt => {
evnt.stopPropagation();
handleFieldMove(index, 'down');
}, onFocus: evnt => evnt.stopPropagation() }, { children: jsx(Tooltip, Object.assign({ title: "Move Down" }, { children: jsx(ExpandMoreIcon, {}) })) }))), jsx(IconButton, Object.assign({ onClick: evnt => {
evnt.stopPropagation();
handleFieldDelete(index);
}, onFocus: evnt => evnt.stopPropagation() }, { children: jsx(Tooltip, Object.assign({ title: "Delete Field" }, { children: jsx(DeleteForeverIcon, {}) })) }))] }))] })), jsx(AccordionDetails, { children: jsxs(Grid, Object.assign({ container: true, spacing: 2 }, { children: [jsx(Grid, Object.assign({ item: true, xs: 10 }, { children: jsx(TextField, { value: fields[index].name, onChange: evnt => {
setFields(preValues => {
const cloneData = [...preValues];
cloneData[index].name = String(evnt.target.value);
return cloneData;
});
}, label: `Field Name ${fields[index].name.length}/256`, fullWidth: true, error: fields[index].name.length < 1 || fields[index].name.length >= 256, required: true }) })), jsx(Grid, Object.assign({ item: true, xs: 2, className: classes.controlPadding }, { children: jsx(FormControlLabel, { control: jsx(Switch, { checked: field.inline, onChange: evnt => {
setFields(preValues => {
const cloneData = [...preValues];
cloneData[index].inline = evnt.target.checked;
return cloneData;
});
} }), label: "Inline" }) })), jsx(Grid, Object.assign({ item: true, xs: 12 }, { children: jsx(TextField, { value: fields[index].value, onChange: evnt => {
setFields(preValues => {
const cloneData = [...preValues];
cloneData[index].value = String(evnt.target.value);
return cloneData;
});
}, label: `Field Value ${fields[index].value.length}/1024`, fullWidth: true, error: fields[index].value.length >= 1024, required: true, multiline: true, rows: 6 }) }))] })) })] }), `field-${index}`))) })) })), jsx(Button, Object.assign({ variant: "contained", onClick: handleFieldAdd, disabled: fields != null ? fields.length === 25 : false }, { children: "Add Field" }))] })] }))), shouldHideFields['images'] === false && (jsxs(Accordion, Object.assign({ expanded: expanded === 'image', onChange: handleAccordian('image') }, { children: [jsx(AccordionSummary, Object.assign({ expandIcon: jsx(ExpandMoreIcon, {}) }, { children: jsx(Typography, Object.assign({ variant: "h5" }, { children: "Images" })) })), jsx(AccordionDetails, { children: jsxs(Grid, Object.assign({ container: true, spacing: 2 }, { children: [jsx(Grid, Object.assign({ item: true, xs: 8 }, { children: jsx(TextField, { value: image.url, onChange: evnt => setImage(preValues => { return Object.assign(Object.assign({}, preValues), { url: String(evnt.target.value) }); }), label: "Image URL", fullWidth: true }) })), jsx(Grid, Object.assign({ item: true, xs: 2 }, { children: jsx(TextField, { value: image.height, onChange: evnt => setImage(preValues => { return Object.assign(Object.assign({}, preValues), { height: Number(evnt.target.value) }); }), label: "Image Height", fullWidth: true, type: "number", inputProps: {
step: 1,
min: 0
} }) })), jsx(Grid, Object.assign({ item: true, xs: 2 }, { children: jsx(TextField, { value: image.width, onChange: evnt => setImage(preValues => { return Object.assign(Object.assign({}, preValues), { width: Number(evnt.target.value) }); }), label: "Image Width", fullWidth: true, type: "number", inputProps: {
step: 1,
min: 0
} }) })), jsx(Grid, Object.assign({ item: true, xs: 8 }, { children: jsx(TextField, { value: thumbnail.url, onChange: evnt => setThumbnail(preValues => { return Object.assign(Object.assign({}, preValues), { url: String(evnt.target.value) }); }), label: "Thumbnail URL", fullWidth: true }) })), jsx(Grid, Object.assign({ item: true, xs: 2 }, { children: jsx(TextField, { value: thumbnail.height, onChange: evnt => setThumbnail(preValues => { return Object.assign(Object.assign({}, preValues), { height: Number(evnt.target.value) }); }), label: "Thumbnail Height", fullWidth: true, type: "number", inputProps: {
step: 1,
min: 0
} }) })), jsx(Grid, Object.assign({ item: true, xs: 2 }, { children: jsx(TextField, { value: thumbnail.width, onChange: evnt => setThumbnail(preValues => { return Object.assign(Object.assign({}, preValues), { width: Number(evnt.target.value) }); }), label: "Thumbnail Width", fullWidth: true, type: "number", inputProps: {
step: 1,
min: 0
} }) }))] })) })] }))), shouldHideFields['footer'] === false && (jsxs(Accordion, Object.assign({ expanded: expanded === 'footer', onChange: handleAccordian('footer') }, { children: [jsx(AccordionSummary, Object.assign({ expandIcon: jsx(ExpandMoreIcon, {}) }, { children: jsx(Typography, Object.assign({ variant: "h5" }, { children: "Footer" })) })), jsx(AccordionDetails, { children: jsxs(Grid, Object.assign({ container: true, spacing: 2 }, { children: [jsx(Grid, Object.assign({ item: true, xs: 12 }, { children: jsx(TextField, { value: footer.text, onChange: evnt => setFooter(preValues => { return Object.assign(Object.assign({}, preValues), { text: String(evnt.target.value) }); }), label: `Footer ${((_c = footer.text) === null || _c === void 0 ? void 0 : _c.length) || 0}/256`, fullWidth: true, error: (((_d = footer.text) === null || _d === void 0 ? void 0 : _d.length) || 0) >= 256 }) })), jsx(Grid, Object.assign({ item: true, xs: 6 }, { children: jsx(TextField, { value: footer.iconUrl, onChange: evnt => setFooter(preValues => { return Object.assign(Object.assign({}, preValues), { iconUrl: String(evnt.target.value) }); }), label: "Footer Icon URL", helperText: "Full path to an icon to use on the footer.", fullWidth: true }) })), jsx(Grid, Object.assign({ item: true, xs: 6 }, { children: jsx(DateTimePicker, { renderInput: props => jsx(TextField, Object.assign({ fullWidth: true }, props)), value: timestamp, onChange: date => {
if (date != null) {
setTimestamp(new Date(date).toString());
}
}, label: "Timestamp" }) }))] })) })] }))), showExportSection && (jsxs(Accordion, Object.assign({ expanded: expanded === 'export', onChange: handleAccordian('export') }, { children: [jsx(AccordionSummary, Object.assign({ expandIcon: jsx(ExpandMoreIcon, {}) }, { children: jsx(Typography, Object.assign({ variant: "h5" }, { children: "Export" })) })), jsx(AccordionDetails, { children: jsxs(Grid, Object.assign({ container: true, spacing: 2 }, { children: [jsx(Grid, Object.assign({ item: true, xs: 6 }, { children: jsx(Select, Object.assign({ fullWidth: true, value: exporter, onChange: evnt => setExporter(evnt.target.value) }, { children: jsx(MenuItem, Object.assign({ value: "discordjs" }, { children: "Discord.js" })) })) })), jsx(Grid, Object.assign({ item: true, xs: 6 }, { children: jsx(Button, Object.assign({ variant: "contained", onClick: handleExport }, { children: "Export" })) }))] })) })] })))] }) })) })) })));
}
Generator.propTypes = {
defaultValue: PropTypes.object.isRequired,
export: PropTypes.bool,
onChange: PropTypes.func.isRequired,
};
Generator.defaultProps = {
defaultValue: {},
showExportSection: true,
onChange: null,
};
const MAX_FIELDS_PER_ROW = 3;
const FIELD_GRID_SIZE = 12;
const getFieldGridColumn = (fields, fieldIndex) => {
const field = fields[fieldIndex];
if (!field.inline) {
return `1 / ${FIELD_GRID_SIZE + 1}`;
}
let startingField = fieldIndex;
while (startingField > 0 && fields[startingField - 1].inline) {
startingField -= 1;
}
let totalInlineFields = 0;
while (fields.length > startingField + totalInlineFields && fields[startingField + totalInlineFields].inline) {
totalInlineFields += 1;
}
const indexInSequence = fieldIndex - startingField;
const currentRow = indexInSequence / MAX_FIELDS_PER_ROW;
const indexOnRow = indexInSequence % MAX_FIELDS_PER_ROW;
const totalOnLastRow = totalInlineFields % MAX_FIELDS_PER_ROW || MAX_FIELDS_PER_ROW;
const fullRows = (totalInlineFields - totalOnLastRow) / MAX_FIELDS_PER_ROW;
const totalOnRow = currentRow >= fullRows ? totalOnLastRow : MAX_FIELDS_PER_ROW;
const columnSpan = FIELD_GRID_SIZE / totalOnRow;
const start = indexOnRow * columnSpan + 1;
const end = start + columnSpan;
return `${start} / ${end}`;
};
const visualizerStyles = makeStyles({
root: {
fontFamily: 'Whitney, "Helvetica Neue", Helvetica, Arial, sans-serif',
},
message: {
padding: '.5rem 1rem .5rem 4.5rem',
},
title: {
display: 'inline-block',
lineHeight: '1.375rem',
minHeight: '1.375rem',
whiteSpace: 'break-spaces',
position: 'relative',
marginLeft: '-4.5rem',
marginBottom: '.3rem',
paddingLeft: '4.5rem',
},
username: {
display: 'inline',
verticalAlign: 'baseline',
margin: '0px .25rem 0px 0px',
color: 'rgb(255, 255, 255)',
fontSize: '1rem',
fontWeight: 500,
lineHeight: '1.375rem',
overflowWrap: 'break-word',
cursor: 'pointer',
},
botBadge: {
position: 'relative',
top: '-0.1rem',
minHeight: '1.275em',
maxHeight: '1.275em',
margin: '.075em .25rem 0px 0px',
padding: '.071875rem .275rem',
borderRadius: '3px',
background: 'rgb(114, 137, 218)',
color: 'rgb(255, 255, 255)',
fontSize: '0.625em',
fontWeight: 500,
lineHeight: 1.3,
verticalAlign: 'baseline',
},
avatar: {
height: '2.5rem',
width: '2.5rem',
position: 'absolute',
left: 0,
top: '0.125rem',
margin: '0 1rem',
borderRadius: '50%',
objectFit: 'cover',
},
});
const embedStyles = makeStyles({
root: {
maxWidth: '520px',
borderLeftWidth: '4px',
borderLeftStyle: 'solid',
backgroundColor: '#2F3136',
color: '#FFF',
},
grid: {
padding: '.5rem 1rem 1rem .75rem',
display: 'inline-grid',
gridTemplateColumns: 'auto',
gridTemplateRows: 'row',
},
wrapper: {
minWidth: '0px',
display: 'inline-block',
margin: '8px 0px 0px',
gridColumn: '1 / 2',
},
body: {},
title: {
fontSize: '1rem',
fontWeight: 600,
margin: '8px 0px 0px',
color: 'rgb(255, 255, 255)',
},
url: {
color: '#00b0f4',
},
description: {
minWidth: '0px',
margin: '8px 0px 0px',
gridColumn: '1 / 2',
},
});
const authorAndFooterStyles = makeStyles({
root: {
fontSize: '0.875rem',
fontWeight: 500,
minWidth: '0px',
display: 'flex',
boxAlign: 'center',
alignItems: 'center',
gridColumn: '1 / 2',
margin: '8px 0px 0px',
},
icon: {
height: '24px',
width: '24px',
margin: '0px 8px 0px 0px',
objectFit: 'contain',
borderRadius: '50%',
},
url: {
color: 'rgb(255, 255, 255)',
whiteSpace: 'pre-wrap',
display: 'inline-block',
},
});
const fieldStyles = makeStyles((theme) => ({
root: {
// minWidth: '0px',
// margin: '8px 0px 0px',
minWidth: 0,
margin: '8px 0px, 0px',
display: 'grid',
gridColumn: 1 / 2,
gridGap: 8,
},
chunk: {
display: 'grid',
},
field: {
minWidth: '0px',
fontSize: '0.875rem',
lineHeight: '1.125rem',
},
name: {
minWidth: '0px',
margin: '0px 0px 1px',
fontSize: '0.875rem',
fontWeight: 600,
color: 'rgb(255, 255, 255)',
whiteSpace: 'pre-wrap',
overflowWrap: 'break-word',
},
value: {
fontSize: '.875rem',
lineHeight: '1.125rem',
color: 'rgb(220, 221, 222)',
whiteSpace: 'pre-line',
'& code': {
backgroundColor: '#202225',
borderRadius: 2,
padding: theme.spacing(.2),
},
'& a': {
color: '#00b0f4',
textDecoration: 'none',
},
},
}));
const imageStyles = makeStyles({
root: {
gridColumn: '1 / 2',
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gridTemplateRows: '1fr 1fr',
gap: '4px',
height: '300px',
marginTop: '16px',
borderRadius: '4px',
overflow: 'hidden',
},
image: {
borderRadius: '4px',
maxWidth: '100%',
userSelect: 'none',
userDrag: 'none',
},
thumbnail: {
maxWidth: 80,
maxHeight: 80,
borderRadius: 4,
margin: '8px 0px 0px 16px',
justifySelf: 'end',
cursor: 'pointer',
gridArea: '1 / 2 / 8 / 3',
userSelect: 'none',
userDrag: 'none',
}
});
function Visualizer(props) {
var _a, _b;
const { bot, embed } = props;
const authorAndFooterClasses = authorAndFooterStyles();
const embedClasses = embedStyles();
const fieldClasses = fieldStyles();
const imageClasses = imageStyles();
const visualizerClasses = visualizerStyles();
return (jsx(ThemeProvider, Object.assign({ theme: theme }, { children: jsx(StyledEngineProvider, Object.assign({ injectFirst: true }, { children: jsx("div", Object.assign({ className: visualizerClasses.root }, { children: jsxs(Paper, Object.assign({ className: visualizerClasses.message }, { children: [jsxs("div", Object.assign({ className: visualizerClasses.title }, { children: [jsx("img", { className: visualizerClasses.avatar, src: bot.iconUrl }), jsx("h1", Object.assign({ className: visualizerClasses.username }, { children: bot.name })), jsx("span", Object.assign({ className: visualizerClasses.botBadge }, { children: "BOT" }))] })), jsx(Paper, Object.assign({ elevation: 0, className: embedClasses.root, style: {
borderLeftColor: `#${embed === null || embed === void 0 ? void 0 : embed.color}` || green[500],
display: 'grid',
} }, { children: jsxs("div", Object.assign({ className: embedClasses.grid }, { children: [embed.author != null && (jsxs("div", Object.assign({ className: authorAndFooterClasses.root }, { children: [embed.author.iconUrl && jsx("img", { className: authorAndFooterClasses.icon, src: embed.author.iconUrl }), embed.author.url
? jsx(Link, Object.assign({ className: authorAndFooterClasses.url, href: embed.author.url }, { children: embed.author.name }))
: embed.author.name] }))), jsx("span", Object.assign({ className: embedClasses.body }, { children: jsx("div", Object.assign({ className: embedClasses.title }, { children: embed.url
? jsx(Link, Object.assign({ className: embedClasses.url, href: embed.url }, { children: embed.title }))
: embed.title })) })), jsx("div", Object.assign({ className: embedClasses.description }, { children: jsx(ReactMarkdown, Object.assign({ remarkPlugins: [gfm] }, { children: embed.description })) })), embed.fields != null && (jsx("div", Object.assign({ className: fieldClasses.root }, { children: embed.fields.map((field, index) => (jsxs("div", Object.assign({ style: { gridColumn: getFieldGridColumn(embed.fields, index) } }, { children: [jsx("div", Object.assign({ className: fieldClasses.name }, { children: field.name })), jsx("div", Object.assign({ className: fieldClasses.value }, { children: jsx(ReactMarkdown, Object.assign({ remarkPlugins: [gfm] }, { children: field.value })) }))] }), `field-${index}`))) }))), ((_a = embed.image) === null || _a === void 0 ? void 0 : _a.url) && (jsx("img", { className: imageClasses.image, src: embed.image.url, style: {
width: embed.image.width !== 0 && `${embed.image.width}px`,
height: embed.image.height !== 0 && `${embed.image.height}px`,
} })), embed.footer != null && (jsxs("div", Object.assign({ className: authorAndFooterClasses.root }, { children: [embed.footer.iconUrl && jsx("img", { className: authorAndFooterClasses.icon, src: embed.footer.iconUrl }), embed.footer.text, embed.timestamp && jsxs("span", { children: ["\u00A0\u2022\u00A0", format(new Date(embed.timestamp || new Date()), "dd/MM/yyyy")] })] }))), ((_b = embed.thumbnail) === null || _b === void 0 ? void 0 : _b.url) && (jsx("img", { className: imageClasses.thumbnail, src: embed.thumbnail.url, style: {
width: embed.thumbnail.width !== 0 && `${embed.thumbnail.width}px`,
height: embed.thumbnail.height !== 0 && `${embed.thumbnail.height}px`,
} }))] })) }))] })) })) })) })));
}
Visualizer.propTypes = {
bot: PropTypes.exact({
name: PropTypes.string,
iconUrl: PropTypes.string,
}),
embed: PropTypes.object.isRequired,
};
Visualizer.defaultProps = {
bot: {
name: 'BeepBot',
iconUrl: 'https://static-cdn.jtvnw.net/jtv_user_pictures/52779398-2481-4700-9648-b94ed5240781-profile_image-70x70.png',
},
embed: {},
};
export { Generator, Visualizer };
//# sourceMappingURL=index.esm.js.map