Spaces:
Configuration error
Configuration error
| import { IconClipboard, IconDownload } from '@tabler/icons' | |
| import { memo, useState } from 'react' | |
| import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' | |
| import { oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism' | |
| import PropTypes from 'prop-types' | |
| import { Box, IconButton, Popover, Typography } from '@mui/material' | |
| import { useTheme } from '@mui/material/styles' | |
| const programmingLanguages = { | |
| javascript: '.js', | |
| python: '.py', | |
| java: '.java', | |
| c: '.c', | |
| cpp: '.cpp', | |
| 'c++': '.cpp', | |
| 'c#': '.cs', | |
| ruby: '.rb', | |
| php: '.php', | |
| swift: '.swift', | |
| 'objective-c': '.m', | |
| kotlin: '.kt', | |
| typescript: '.ts', | |
| go: '.go', | |
| perl: '.pl', | |
| rust: '.rs', | |
| scala: '.scala', | |
| haskell: '.hs', | |
| lua: '.lua', | |
| shell: '.sh', | |
| sql: '.sql', | |
| html: '.html', | |
| css: '.css' | |
| } | |
| export const CodeBlock = memo(({ language, chatflowid, isDialog, value }) => { | |
| const theme = useTheme() | |
| const [anchorEl, setAnchorEl] = useState(null) | |
| const openPopOver = Boolean(anchorEl) | |
| const handleClosePopOver = () => { | |
| setAnchorEl(null) | |
| } | |
| const copyToClipboard = (event) => { | |
| if (!navigator.clipboard || !navigator.clipboard.writeText) { | |
| return | |
| } | |
| navigator.clipboard.writeText(value) | |
| setAnchorEl(event.currentTarget) | |
| setTimeout(() => { | |
| handleClosePopOver() | |
| }, 1500) | |
| } | |
| const downloadAsFile = () => { | |
| const fileExtension = programmingLanguages[language] || '.file' | |
| const suggestedFileName = `file-${chatflowid}${fileExtension}` | |
| const fileName = suggestedFileName | |
| if (!fileName) { | |
| // user pressed cancel on prompt | |
| return | |
| } | |
| const blob = new Blob([value], { type: 'text/plain' }) | |
| const url = URL.createObjectURL(blob) | |
| const link = document.createElement('a') | |
| link.download = fileName | |
| link.href = url | |
| link.style.display = 'none' | |
| document.body.appendChild(link) | |
| link.click() | |
| document.body.removeChild(link) | |
| URL.revokeObjectURL(url) | |
| } | |
| return ( | |
| <div style={{ width: isDialog ? '' : 300 }}> | |
| <Box sx={{ color: 'white', background: theme.palette?.common.dark, p: 1, borderTopLeftRadius: 10, borderTopRightRadius: 10 }}> | |
| <div style={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}> | |
| {language} | |
| <div style={{ flex: 1 }}></div> | |
| <IconButton size='small' title='Copy' color='success' onClick={copyToClipboard}> | |
| <IconClipboard /> | |
| </IconButton> | |
| <Popover | |
| open={openPopOver} | |
| anchorEl={anchorEl} | |
| onClose={handleClosePopOver} | |
| anchorOrigin={{ | |
| vertical: 'top', | |
| horizontal: 'right' | |
| }} | |
| transformOrigin={{ | |
| vertical: 'top', | |
| horizontal: 'left' | |
| }} | |
| > | |
| <Typography variant='h6' sx={{ pl: 1, pr: 1, color: 'white', background: theme.palette.success.dark }}> | |
| Copied! | |
| </Typography> | |
| </Popover> | |
| <IconButton size='small' title='Download' color='primary' onClick={downloadAsFile}> | |
| <IconDownload /> | |
| </IconButton> | |
| </div> | |
| </Box> | |
| <SyntaxHighlighter language={language} style={oneDark} customStyle={{ margin: 0 }}> | |
| {value} | |
| </SyntaxHighlighter> | |
| </div> | |
| ) | |
| }) | |
| CodeBlock.displayName = 'CodeBlock' | |
| CodeBlock.propTypes = { | |
| language: PropTypes.string, | |
| chatflowid: PropTypes.string, | |
| isDialog: PropTypes.bool, | |
| value: PropTypes.string | |
| } | |