Skip to content

Commit

Permalink
run rust
Browse files Browse the repository at this point in the history
  • Loading branch information
JYC0413 committed Sep 12, 2024
1 parent e22d262 commit 91735b0
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 78 deletions.
202 changes: 124 additions & 78 deletions components/Markdown/CodeBlock.tsx
Original file line number Diff line number Diff line change
@@ -1,94 +1,140 @@
import { IconCheck, IconClipboard, IconDownload } from '@tabler/icons-react';
import { FC, memo, useState } from 'react';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import {IconCheck, IconClipboard, IconDownload, IconPlayerPlay, IconTruckLoading} from '@tabler/icons-react';
import {FC, memo, useState} from 'react';
import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter';
import {oneDark} from 'react-syntax-highlighter/dist/cjs/styles/prism';

import { useTranslation } from 'next-i18next';
import {useTranslation} from 'next-i18next';

import {
generateRandomString,
programmingLanguages,
} from '@/utils/app/codeblock';
import {generateRandomString, programmingLanguages,} from '@/utils/app/codeblock';

interface Props {
language: string;
value: string;
language: string;
value: string;
}

export const CodeBlock: FC<Props> = memo(({ language, value }) => {
const { t } = useTranslation('markdown');
const [isCopied, setIsCopied] = useState<Boolean>(false);
interface std {
success?: boolean,
exitDetail?: string,
stdout?: string,
stderr?: string
}

const copyToClipboard = () => {
if (!navigator.clipboard || !navigator.clipboard.writeText) {
return;
}
export const CodeBlock: FC<Props> = memo(({language, value}) => {
const {t} = useTranslation('markdown');
const [isCopied, setIsCopied] = useState<Boolean>(false);
const [runLoad, setRunLoad] = useState<Boolean>(false);
const [std, setStd] = useState<std>({});

navigator.clipboard.writeText(value).then(() => {
setIsCopied(true);
const copyToClipboard = () => {
if (!navigator.clipboard || !navigator.clipboard.writeText) {
return;
}

setTimeout(() => {
setIsCopied(false);
}, 2000);
});
};
const downloadAsFile = () => {
const fileExtension = programmingLanguages[language] || '.file';
const suggestedFileName = `file-${generateRandomString(
3,
true,
)}${fileExtension}`;
const fileName = window.prompt(
t('Enter file name') || '',
suggestedFileName,
);
navigator.clipboard.writeText(value).then(() => {
setIsCopied(true);

setTimeout(() => {
setIsCopied(false);
}, 2000);
});
};
const downloadAsFile = () => {
const fileExtension = programmingLanguages[language] || '.file';
const suggestedFileName = `file-${generateRandomString(
3,
true,
)}${fileExtension}`;
const fileName = window.prompt(
t('Enter file name') || '',
suggestedFileName,
);

if (!fileName) {
// user pressed cancel on prompt
return;
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);
};

const runRust = async () => {
setRunLoad(true)
try {
const response = await fetch('https://play.rust-lang.org/execute', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
channel: 'stable',
mode: 'debug',
crateType: 'bin',
edition: '2021',
code: value,
tests: false,
}),
});
const data: std = await response.json()
setStd(data)
}catch (e) {
console.log("run rust error:",e)
}
setRunLoad(false)
}
return (
<div className="codeblock relative font-sans text-[16px] bg-black pb-px">
<div className="flex items-center justify-between py-1.5 px-4">
<span className="text-xs lowercase text-white">{language}</span>

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 className="codeblock relative font-sans text-[16px]">
<div className="flex items-center justify-between py-1.5 px-4">
<span className="text-xs lowercase text-white">{language}</span>
<div className="flex items-center">
<button
className="flex gap-1.5 items-center rounded bg-none p-1 text-xs text-white"
onClick={copyToClipboard}
>
{isCopied ? <IconCheck size={18}/> : <IconClipboard size={18}/>}
{isCopied ? t('Copied!') : t('Copy code')}
</button>
<button
className="flex items-center rounded bg-none p-1 text-xs text-white"
onClick={downloadAsFile}
>
<IconDownload size={18}/>
</button>
{language === "rust" && <button
className="flex items-center rounded bg-none p-1 text-xs text-white"
onClick={runRust}
>
<IconPlayerPlay size={18}/>
</button>}
</div>
</div>

<div className="flex items-center">
<button
className="flex gap-1.5 items-center rounded bg-none p-1 text-xs text-white"
onClick={copyToClipboard}
>
{isCopied ? <IconCheck size={18} /> : <IconClipboard size={18} />}
{isCopied ? t('Copied!') : t('Copy code')}
</button>
<button
className="flex items-center rounded bg-none p-1 text-xs text-white"
onClick={downloadAsFile}
>
<IconDownload size={18} />
</button>
<SyntaxHighlighter
language={language}
style={oneDark}
customStyle={{margin: 0}}
>
{value}
</SyntaxHighlighter>
{
(Object.keys(std).length > 0 || runLoad) && <div className="bg-white m-2 px-4 py-2">
{runLoad ? <div className="text-animation">
<span></span>
<span></span>
<span></span>
</div> : std.success ? ("> "+std.stdout) : std.stderr}
</div>
}
</div>
</div>

<SyntaxHighlighter
language={language}
style={oneDark}
customStyle={{ margin: 0 }}
>
{value}
</SyntaxHighlighter>
</div>
);
);
});
CodeBlock.displayName = 'CodeBlock';
29 changes: 29 additions & 0 deletions styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -360,3 +360,32 @@ pre:has(div.codeblock) {
.landing-swiper .swiper-pagination-bullet-active {
background: #f5f5ef !important;
}

@keyframes colorChange {
0% {
color: black;
}
50% {
color: white;
}
100% {
color: black;
}
}

.text-animation span {
animation: colorChange 1s infinite;
display: inline-block;
}

.text-animation span:nth-child(1) {
animation-delay: 0s;
}

.text-animation span:nth-child(2) {
animation-delay: 0.2s;
}

.text-animation span:nth-child(3) {
animation-delay: 0.4s;
}

0 comments on commit 91735b0

Please sign in to comment.