Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed build/favicon.ico
Binary file not shown.
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@
"@uiw/codemirror-theme-sublime": "4.11.1",
"@uiw/react-codemirror": "4.11.1",
"@vercel/analytics": "^0.1.11",
"@uiw/react-md-editor": "^3.20.6",
"antd": "^5.4.0",
"axios": "0.27.2",
"chatgpt": "^5.2.2",
"openai-authenticator": "^0.0.3",
"ramda": "0.28.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"react-query": "3.39.1",
"react-scripts": "4.0.0",
"react-select": "5.4.0"
"react-select": "5.4.0",
"rehype-sanitize": "^5.0.1",
"uuid": "^9.0.0"
},
"devDependencies": {
"@babel/runtime": "7.13.8",
Expand Down
4 changes: 2 additions & 2 deletions src/Apis/axios.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ const axiosOptions = {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.REACT_APP_OPEN_AI_KEY}`,
"X-RapidAPI-Key": process.env.REACT_APP_JUDGE0_KEY,
"X-RapidAPI-Host": "judge0-ce.p.rapidapi.com"
}
"X-RapidAPI-Host": "judge0-ce.p.rapidapi.com",
},
};

export default axios.create(axiosOptions);
16 changes: 3 additions & 13 deletions src/Apis/refactorCode.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import { ChatGPTUnofficialProxyAPI } from "chatgpt";
import Authenticator from "openai-authenticator";
import axios from "./axios";

const authenticator = new Authenticator();

const api = new ChatGPTUnofficialProxyAPI({
accessToken: authenticator.login(
process.env.REACT_APP_CHATGPT_EMAIL,
process.env.REACT_APP_CHATGPT_PASSWORD
),
apiReverseProxyUrl: "https://bypass.churchless.tech/api/conversation",
});

const createCompletion = (payload) => api.send(payload);
const createCompletion = (payload) =>
axios.post("https://api.openai.com/v1/chat/completions", payload);

export default { createCompletion };
68 changes: 68 additions & 0 deletions src/Components/ChatGptModal/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Modal, Spin } from "antd";
import MDEditor from "@uiw/react-md-editor";
import rehypeSanitize from "rehype-sanitize";

const ChatGptModal = ({
showModal,
setShowModal,
text,
setValue,
getSelectedValue,
isLoading,
}) => {
const extractCodeFromBlock = (blockString) =>
[...blockString.matchAll(/```(?:[a-z]+)?\n([\s\S]+?)\n```/g)].map(
(match) => match[1]
);

const pasteCode = () => {
const selectedValue = getSelectedValue();
const code = extractCodeFromBlock(text);

setValue((prevValue) => prevValue.replace(selectedValue, code));
setShowModal(false);
};

const handleCancel = () => {
setShowModal(false);
};

const Footer = [
<button
className="disabled:opacity-75 disabled:cursor-not-allowed border border-gray-200 bg-gray-200 text-gray-700 rounded-md px-4 py-2 md:m-2 mt-2 transition duration-500 ease select-none hover:bg-gray-300 focus:outline-none focus:shadow-outline"
onClick={handleCancel}
>
Cancel
</button>,
<button
className="disabled:opacity-75 disabled:cursor-not-allowed border border-gray-200 bg-blue-700 text-white rounded-md px-4 py-2 md:m-2 mt-2 transition duration-500 ease select-none hover:bg-gray-300 focus:outline-none focus:shadow-outline"
onClick={pasteCode}
>
Paste Code
</button>,
];

return (
<Modal
title="ChatGPT refactored code"
open={showModal}
footer={Footer}
width={1000}
>
{isLoading ? (
<div className="flex w-full h-full justify-center">
<Spin tip="Loading..." />
</div>
) : (
<MDEditor.Markdown
source={text}
style={{ padding: 10 }}
previewOptions={{
rehypePlugins: [[rehypeSanitize]],
}}
/>
)}
</Modal>
);
};
export default ChatGptModal;
8 changes: 4 additions & 4 deletions src/Components/CodeEditor/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { EditorView } from "@codemirror/view";
import { mapLanguages } from "./utils";

const CodeEditor = ({
editorRef,
editorRef = null,
selectedLanguage,
value,
onChange,
editable,
runCode,
onChange = ()=>{},
editable = false,
runCode = ()=>{},
}) => {
const handleIndentTab = (cm) => {
const spaces = Array(cm.getOption("indentUnit") + 1).join(" ");
Expand Down
118 changes: 73 additions & 45 deletions src/Components/Main.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from "react";
import { v4 as uuidv4 } from "uuid";

import { assoc } from "ramda";

Expand All @@ -18,6 +19,7 @@ import OutputTerminalHeader from "./OutputTerminal/Header";
import { useCreateCompletionApi } from "../Hooks/useRefactorApi";
import Header from "./Header";
import CodeActions from "./CodeActions";
import ChatGptModal from "./ChatGptModal";

const Main = () => {
const outputRef = useRef(null);
Expand All @@ -28,6 +30,8 @@ const Main = () => {
const [input, setInput] = useState();
const [output, setOutput] = useState(DEFAULT_OUTPUT_VALUE);
const [isLoading, setIsLoading] = useState(false);
const [showModal, setShowModal] = useState(false);
const [chatGptOutput, setChatGptOutput] = useState("");

const { mutateAsync: runCode } = useCreateSubmissionsApi();
const { mutateAsync: getOutput } = useGetSubmissionsApi();
Expand Down Expand Up @@ -80,22 +84,36 @@ const Main = () => {
}
};

const getSelectedRangeOfValue = () => {
const cursorSelection = editorRef.current.view.state.selection.main;
const startRange = cursorSelection.from;
const endRange = cursorSelection.to;
return startRange !== endRange
? value.substring(startRange, endRange)
: value;
};

const refactorCode = async () => {
try {
setShowModal(true);
setIsLoading(true);
const cursorSelection = editorRef.current.view.state.selection.main;
const startRange = cursorSelection.from;
const endRange = cursorSelection.to;
const selectedValue =
startRange !== endRange ? value.substring(startRange, endRange) : value;
const selectedValue = getSelectedRangeOfValue();

const chatInput = [
{
role: "system",
content: "You are a chatbot that can refactor any code.",
},
{ role: "user", content: `Refactor code snippet ${selectedValue}` },
];

const { data: chatGptOutput } = await getRefactoredCode({
model: "gpt-3.5-turbo",
messages: [{ role: "user", content: `Refactor code snippet ${selectedValue}` }],
messages: chatInput,
});

const refactoredCode = chatGptOutput.choices[0].message.content;
setValue((prevValue) => prevValue.replace(selectedValue, refactoredCode));
setChatGptOutput(refactoredCode);
} catch (err) {
console.log(err);
} finally {
Expand All @@ -108,45 +126,55 @@ const Main = () => {
};

return (
<div className="flex flex-col p-4">
<Header />
<div className="md:flex md:w-full mt-4 justify-between items-center">
<LanguageSelector
selectedLanguage={selectedLanguage}
setSelectedLanguage={setSelectedLanguage}
/>
<CodeActions
refactorCode={refactorCode}
runEditorCode={runEditorCode}
isLoading={isLoading}
/>
</div>
<div className="editor-height mt-5">
<CodeEditor
editorRef={editorRef}
selectedLanguage={selectedLanguage?.title.toLowerCase()}
value={value}
onChange={setValue}
editable={!isLoading}
runCode={runEditorCode}
/>
</div>
<div className="flex flex-col mt-5">
<CustomInputHeader clearInput={clearInput} />
<CustomInput input={input} setInput={handleCustomInputChange} />
<>
<div className="flex flex-col p-4">
<Header />
<div className="md:flex md:w-full mt-4 justify-between items-center">
<LanguageSelector
selectedLanguage={selectedLanguage}
setSelectedLanguage={setSelectedLanguage}
/>
<CodeActions
refactorCode={refactorCode}
runEditorCode={runEditorCode}
isLoading={isLoading}
/>
</div>
<div className="editor-height mt-5">
<CodeEditor
editorRef={editorRef}
selectedLanguage={selectedLanguage?.title.toLowerCase()}
value={value}
onChange={setValue}
editable={!isLoading}
runCode={runEditorCode}
/>
</div>
<div className="flex flex-col mt-5">
<CustomInputHeader clearInput={clearInput} />
<CustomInput input={input} setInput={handleCustomInputChange} />
</div>
{output.data && (
<>
<div className="flex flex-col py-4">
<OutputTerminalHeader
status={output?.status}
clearOutput={clearOutput}
/>
<OutputTerminal output={output?.data} outputRef={outputRef} />
</div>
</>
)}
</div>
{output.data && (
<>
<div className="flex flex-col py-4">
<OutputTerminalHeader
status={output?.status}
clearOutput={clearOutput}
/>
<OutputTerminal output={output?.data} outputRef={outputRef} />
</div>
</>
)}
</div>
<ChatGptModal
showModal={showModal}
setShowModal={setShowModal}
text={chatGptOutput}
setValue={setValue}
getSelectedValue={getSelectedRangeOfValue}
isLoading={isLoading}
/>
</>
);
};

Expand Down