Skip to content

Commit

Permalink
πŸš€ [FEAT: ] Download code feature
Browse files Browse the repository at this point in the history
Merge pull request #112 from amaan-ahmad/download_code
  • Loading branch information
kothariji authored Apr 12, 2021
2 parents 3cb90f3 + baab372 commit 57b5343
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 52 deletions.
151 changes: 113 additions & 38 deletions frontend/syntaxmeets/src/components/SyntaxEditor/SyntaxEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
DialogTitle,
DialogActions,
Snackbar,
ButtonGroup,
} from "@material-ui/core";
import Grid from "@material-ui/core/Grid";
import Alert from "@material-ui/lab/Alert";
Expand All @@ -33,12 +34,14 @@ import {
import ShareIcon from "@material-ui/icons/Share";
import PlayArrowIcon from "@material-ui/icons/PlayArrow";
import FileCopyIcon from "@material-ui/icons/FileCopy";
import CloudUploadIcon from '@material-ui/icons/CloudUpload';
import CloudUploadIcon from "@material-ui/icons/CloudUpload";
import INPUT from "./CodeInput";
import OUTPUT from "./CodeOutput";
import copy from "copy-to-clipboard";
import { connect } from "react-redux";
import * as actions from "../../store/actions/editorActions.js";
import CloudDownloadRounded from "@material-ui/icons/CloudDownloadRounded";
import { getExtensionByLangCode } from "../../util/util";
//extracting all the languages recquired
languages.forEach((lang) => {
require(`ace-builds/src-noconflict/mode-${lang}`);
Expand All @@ -58,7 +61,39 @@ const useStyles = makeStyles((mutheme) => ({
},
}));

const validExtensions = [".c", ".cpp", ".java", ".js", ".ts", ".clj", ".cljs", ".cs", ".cbl", ".cob", ".cpy", ".erl", ".hrl", ".go", ".py", ".f90", ".f95", ".f03", ".txt", ".groovy", ".gvy", ".gy", ".gsh", ".kt", ".kts", ".ktm", ".php", ".r", ".rb", ".sql", ".swift"];
const validExtensions = [
".c",
".cpp",
".java",
".js",
".ts",
".clj",
".cljs",
".cs",
".cbl",
".cob",
".cpy",
".erl",
".hrl",
".go",
".py",
".f90",
".f95",
".f03",
".txt",
".groovy",
".gvy",
".gy",
".gsh",
".kt",
".kts",
".ktm",
".php",
".r",
".rb",
".sql",
".swift",
];

const SyntaxEditor = (props) => {
const [theme, setTheme] = useState("monokai");
Expand Down Expand Up @@ -93,6 +128,20 @@ const SyntaxEditor = (props) => {
props.executeCode(langId[props.currLang], props.code, props.codeInput);
};

const handleCodeDownload = () => {
// download code here...
const element = document.createElement("a");
const file = new Blob([props.code], {
type: "text/plain;charset=utf-8",
});
element.href = URL.createObjectURL(file);
element.download = `syntaxmeets-code.${getExtensionByLangCode(
props.currLang
)}`;
document.body.appendChild(element);
element.click();
};

const IONavbar = (props) => {
return (
<AppBar position="static" style={{ backgroundColor: "#000A29" }}>
Expand All @@ -114,29 +163,32 @@ const SyntaxEditor = (props) => {
</AppBar>
);
};

const uploadFile = () => {
document.querySelector("#upload").click();
}
};

const checkValidFileExtension = (file) => {
var name = file.name;
var valid = false;
if (name.length > 0) {
for (var i = 0; i < validExtensions.length; ++i) {
var ext = validExtensions[i];
if (name.substr(name.length - ext.length, ext.length).toLowerCase() == ext.toLowerCase()) {
if (
name.substr(name.length - ext.length, ext.length).toLowerCase() ==
ext.toLowerCase()
) {
valid = true;
break;
}
}
}
return valid;
}
};

const handleFileChange = () => {
var file = document.querySelector("#upload").files[0];

if (file) {
var reader = new FileReader();

Expand All @@ -160,7 +212,7 @@ const SyntaxEditor = (props) => {

reader.readAsText(file, "UTF-8");
}
}
};

return (
<Fragment>
Expand Down Expand Up @@ -346,39 +398,62 @@ const SyntaxEditor = (props) => {
}
label={
<Typography>
<span style={{ color: "white" }}>Enable Auto-complete</span>
<span style={{ color: "white" }}>Auto-complete</span>
</Typography>
}
/>
<input type="file" id="upload" onChange={() => handleFileChange()} hidden accept=".c, .cpp, .java, .js, .ts, .clj, .cljs, .cs, .cbl, .cob, .cpy, .erl, .hrl, .go, .py, .f90, .f95, .f03, .txt, .groovy, .gvy, .gy, .gsh, .kt, .kts, .ktm, .php, .r, .rb, .sql, .swift"/>
<Button
variant="contained"
color="primary"
onClick={() => uploadFile()}
startIcon={<CloudUploadIcon />}
style={{
fontFamily: "poppins",
marginLeft: "auto",
fontWeight: "600",
color: "white",
}}
>
Upload File
</Button>
<Button
<input
type="file"
id="upload"
onChange={() => handleFileChange()}
hidden
accept=".c, .cpp, .java, .js, .ts, .clj, .cljs, .cs, .cbl, .cob, .cpy, .erl, .hrl, .go, .py, .f90, .f95, .f03, .txt, .groovy, .gvy, .gy, .gsh, .kt, .kts, .ktm, .php, .r, .rb, .sql, .swift"
/>
<ButtonGroup
style={{ marginLeft: "auto" }}
variant="contained"
color="primary"
onClick={() => copyCode(props.code)}
startIcon={<FileCopyIcon />}
style={{
fontFamily: "poppins",
marginLeft: "auto",
fontWeight: "600",
color: "white",
}}
>
Copy
</Button>
<Button
variant="contained"
color="primary"
onClick={() => uploadFile()}
style={{
fontFamily: "poppins",
marginLeft: "auto",
fontWeight: "600",
color: "white",
}}
>
<CloudUploadIcon />
</Button>
<Button
variant="contained"
color="primary"
onClick={() => copyCode(props.code)}
style={{
fontFamily: "poppins",
marginLeft: "auto",
fontWeight: "600",
color: "white",
}}
>
<FileCopyIcon />
</Button>
<Button
variant="contained"
color="primary"
style={{
fontFamily: "poppins",
marginLeft: "auto",
fontWeight: "600",
color: "white",
}}
onClick={handleCodeDownload}
>
<CloudDownloadRounded style={{ fontSize: 24 }} />
</Button>
</ButtonGroup>
<Button
variant="contained"
color="primary"
Expand Down Expand Up @@ -422,8 +497,8 @@ const mapStateToProps = (state) => {
isCompiling: state.EDITOR.isCompiling,
isError: state.EDITOR.isError,
codeError: state.EDITOR.codeError,
previousUser:state.ROOM.previousUser,
id:state.ROOM.id
previousUser: state.ROOM.previousUser,
id: state.ROOM.id,
};
};

Expand All @@ -438,4 +513,4 @@ const mapDispatchToProps = (dispatch) => {
dispatch(actions.executeCode(langId, code, input)),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(SyntaxEditor);
export default connect(mapStateToProps, mapDispatchToProps)(SyntaxEditor);
75 changes: 61 additions & 14 deletions frontend/syntaxmeets/src/util/util.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,66 @@
export const generateRoomId = () => {
var tempId = "";
var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var charactersLength = characters.length;
for (var i = 0; i < 12; i++) {
tempId += characters.charAt(Math.floor(Math.random() * charactersLength));
if ((i + 1) % 4 === 0 && i !== 11) {
tempId += "-";
}
var tempId = "";
var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var charactersLength = characters.length;
for (var i = 0; i < 12; i++) {
tempId += characters.charAt(Math.floor(Math.random() * charactersLength));
if ((i + 1) % 4 === 0 && i !== 11) {
tempId += "-";
}
return tempId;
}
}
return tempId;
};

export const validateRoomID = (roomId) => {
var patt = new RegExp("(([A-Za-z]{4})(-)){2}[A-Za-z]{4}");
return patt.test(roomId.trim()) && roomId.length == 14;
};

var patt = new RegExp("(([A-Za-z]{4})(-)){2}[A-Za-z]{4}");
return patt.test(roomId.trim()) && roomId.length == 14;

}
export const getExtensionByLangCode = (langCode) => {
switch (langCode) {
case "C++":
return "cpp";
case "C":
return "c";
case "JAVA":
return "java";
case "Python":
return "py";
case "JavaScript":
return "js";
case "TypeScript":
return "ts";
case "Clojure":
return "clj";
case "C#":
return "cs";
case "COBOL":
return "cbl";
case "COBOL":
return "cob";
case "Erlang":
return "erl";
case "Go":
return "go";
case "Python":
return "py";
case "FortRan":
return "f90";
case "Groovy":
return "groovy";
case "Kotlin":
return "kt";
case "PHP":
return "php";
case "R":
return "r";
case "Ruby":
return "rb";
case "SQL":
return "sql";
case "Swift":
return "swift";
default:
return "txt";
}
};

1 comment on commit 57b5343

@vercel
Copy link

@vercel vercel bot commented on 57b5343 Apr 12, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.