UNPKG

discord-embed-visualizer

Version:

<div align="center">

838 lines (823 loc) 46.7 kB
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