From da5e9b2b0008c002ac13019e85c86ed9a0fbbdce Mon Sep 17 00:00:00 2001 From: Amelia Wattenberger Date: Wed, 20 Apr 2022 12:33:51 -0700 Subject: [PATCH 1/2] add edit code block --- package.json | 19 ++- src/blocks/file-blocks/edit/index.css | 114 +++++++++++++++ src/blocks/file-blocks/edit/index.tsx | 192 ++++++++++++++++++++++++++ yarn.lock | 36 ++++- 4 files changed, 358 insertions(+), 3 deletions(-) create mode 100644 src/blocks/file-blocks/edit/index.css create mode 100644 src/blocks/file-blocks/edit/index.tsx diff --git a/package.json b/package.json index 45aaa77..57f5c40 100644 --- a/package.json +++ b/package.json @@ -321,6 +321,21 @@ ], "example_path": "https://github.com/mattdesl/canvas-sketch/blob/master/lib/save.js" }, + { + "type": "file", + "id": "edit-block", + "title": "Edit code", + "description": "Edit code by prompting a Machine Learning model", + "sandbox": false, + "entry": "/src/blocks/file-blocks/edit/index.tsx", + "extensions": [ + "*" + ], + "matches": [ + "*" + ], + "example_path": "https://github.com/githubnext/blocks-tutorial/blob/main/processing-sketch.js" + }, { "type": "folder", "id": "minimap-block", @@ -424,6 +439,7 @@ "p5": "^1.4.1", "papaparse": "^5.3.1", "react": "^17.0.0", + "react-diff-view": "^2.4.8", "react-dom": "^17.0.0", "react-error-boundary": "^3.1.4", "react-image-annotation": "^0.9.10", @@ -436,7 +452,8 @@ "recharts": "^2.1.6", "rlayers": "^1.3.2", "styled-components": "^5.3.3", - "three": "^0.134.0" + "three": "^0.134.0", + "unidiff": "^1.0.2" }, "resolutions": { "react": "17.0.0", diff --git a/src/blocks/file-blocks/edit/index.css b/src/blocks/file-blocks/edit/index.css new file mode 100644 index 0000000..03e6c35 --- /dev/null +++ b/src/blocks/file-blocks/edit/index.css @@ -0,0 +1,114 @@ +.hljs { + color: #24292e; + background: #ffffff; +} + +.hljs-doctag, +.hljs-keyword, +.hljs-meta .hljs-keyword, +.hljs-template-tag, +.hljs-template-variable, +.hljs-type, +.hljs-variable.language_ { + /* prettylights-syntax-keyword */ + color: #d73a49; +} + +.hljs-title, +.hljs-title.class_, +.hljs-title.class_.inherited__, +.hljs-title.function_ { + /* prettylights-syntax-entity */ + color: #6f42c1; +} + +.hljs-attr, +.hljs-attribute, +.hljs-literal, +.hljs-meta, +.hljs-number, +.hljs-operator, +.hljs-variable, +.hljs-selector-attr, +.hljs-selector-class, +.hljs-selector-id { + /* prettylights-syntax-constant */ + color: #005cc5; +} + +.hljs-regexp, +.hljs-string, +.hljs-meta .hljs-string { + /* prettylights-syntax-string */ + color: #032f62; +} + +.hljs-built_in, +.hljs-symbol { + /* prettylights-syntax-variable */ + color: #e36209; +} + +.hljs-comment, +.hljs-code, +.hljs-formula { + /* prettylights-syntax-comment */ + color: #6a737d; +} + +.hljs-name, +.hljs-quote, +.hljs-selector-tag, +.hljs-selector-pseudo { + /* prettylights-syntax-entity-tag */ + color: #22863a; +} + +.hljs-subst { + /* prettylights-syntax-storage-modifier-import */ + color: #24292e; +} + +.hljs-section { + /* prettylights-syntax-markup-heading */ + color: #005cc5; + font-weight: bold; +} + +.hljs-bullet { + /* prettylights-syntax-markup-list */ + color: #735c0f; +} + +.hljs-emphasis { + /* prettylights-syntax-markup-italic */ + color: #24292e; + font-style: italic; +} + +.hljs-strong { + /* prettylights-syntax-markup-bold */ + color: #24292e; + font-weight: bold; +} + +.hljs-addition { + /* prettylights-syntax-markup-inserted */ + color: #22863a; + background-color: #f0fff4; +} + +.hljs-deletion { + /* prettylights-syntax-markup-deleted */ + color: #b31d28; + background-color: #ffeef0; +} + +.hljs-char.escape_, +.hljs-link, +.hljs-params, +.hljs-property, +.hljs-punctuation, +.hljs-tag { + /* purposely ignored */ +} diff --git a/src/blocks/file-blocks/edit/index.tsx b/src/blocks/file-blocks/edit/index.tsx new file mode 100644 index 0000000..27056c6 --- /dev/null +++ b/src/blocks/file-blocks/edit/index.tsx @@ -0,0 +1,192 @@ +import { FileBlockProps, getLanguageFromFilename } from "@githubnext/utils"; +import { RocketIcon } from "@primer/octicons-react"; +import axios from "axios"; +import { useMemo, useState } from "react"; +import { Hunk, parseDiff } from "react-diff-view"; +import "react-diff-view/style/index.css"; +import SyntaxHighlighter from "react-syntax-highlighter"; +import { diffAsText } from "unidiff"; +import "./index.css"; + +export default function (props: FileBlockProps) { + const { content, context, onRequestUpdateContent } = props; + + const [instruction, setInstruction] = useState(""); + const [newContent, setNewContent] = useState(""); + const [isLoading, setIsLoading] = useState(false); + + const language = getLanguageFromFilename(context.path.split("/").pop() || ""); + + const hunks = useMemo(() => { + if (!newContent) return []; + const hunks = parseDiff( + diffAsText(content, newContent, { + context: 100, + }), + { + nearbySequences: "zip", + } + ); + + return hunks; + }, [content, newContent]); + + return ( +
+
{ + e.preventDefault(); + setIsLoading(true); + const res = await axios.post("/api/openai-edit", { + instruction: instruction, + input: content, + }); + setNewContent(res.data); + setIsLoading(false); + }} + > + +
+ { + setInstruction(e.target.value); + }} + /> + +
+
+ +
+ {newContent && ( +
+
Proposed code
+ +
+ )} +
+ + {newContent ? ( +
+
+ {hunks?.[0]?.hunks?.map((hunk: Hunk) => ( + + ))} +
+
+ ) : ( +
+          
+            {content}
+          
+        
+ )} +
+ ); +} + +const syntaxHighlighterLanguageMap = { + JavaScript: "javascript", + TypeScript: "typescript", +} as Record; + +const HunkComponent = ({ hunk, language }: { hunk: any; language: string }) => { + console.log(hunk); + return ( +
+      {hunk.changes.map((change: Hunk["change"], i: number) => (
+        
+      ))}
+    
+ ); +}; + +const Change = ({ change, language }: { change: Hunk; language: string }) => { + return ( +
+ + {(change.type === "delete" ? "- " : " ") + + (change.type === "insert" ? " " : change.content || " ")} + + + {(change.type === "insert" ? "+ " : " ") + + (change.type === "delete" ? " " : change.content || " ")} + +
+ ); +}; diff --git a/yarn.lock b/yarn.lock index ad3077e..0c73092 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2904,7 +2904,7 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -classnames@2.3.1, classnames@^2.2.5: +classnames@2.3.1, classnames@^2.2.5, classnames@^2.2.6: version "2.3.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== @@ -3908,6 +3908,16 @@ didyoumean@^1.2.2: resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== +diff-match-patch@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz#abb584d5f10cd1196dfc55aa03701592ae3f7b37" + integrity sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw== + +diff@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99" + integrity sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k= + dlv@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" @@ -6568,6 +6578,16 @@ react-devtools-inline@4.4.0: dependencies: es6-symbol "^3" +react-diff-view@^2.4.8: + version "2.4.10" + resolved "https://registry.yarnpkg.com/react-diff-view/-/react-diff-view-2.4.10.tgz#7d38ebd43683f0e506d0d38472c0607e24f30a58" + integrity sha512-H9cyh+a002RyP4BMkSaL4OOBDNhkVpaCA+8oHeb6kS3X9Sj8cZymRHf/CyVkTmm+je/qWMa8Po0VBwSnktQ79w== + dependencies: + classnames "^2.2.6" + diff-match-patch "^1.0.5" + shallow-equal "^1.2.1" + warning "^4.0.2" + react-dom@17.0.0: version "17.0.0" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.0.tgz#f8266e4d9861584553ccbd186d596a1c7dd8dcb4" @@ -7227,6 +7247,11 @@ setimmediate@^1.0.5: resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= +shallow-equal@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da" + integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA== + shallowequal@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" @@ -7955,6 +7980,13 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== +unidiff@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unidiff/-/unidiff-1.0.2.tgz#8706eb36e4aa182a6ca699ecd2f8877f4b906ce0" + integrity sha512-2sbEzki5fBmjgAqoafwxRenfMcumMlmVAoJDwYJa3CI4ZVugkdR6qjTw5sVsl29/4JfBBXhWEAd5ars8nRdqXg== + dependencies: + diff "^2.2.2" + unified@^9.2.0: version "9.2.2" resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" @@ -8203,7 +8235,7 @@ w3c-keyname@^2.2.4: resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.4.tgz#4ade6916f6290224cdbd1db8ac49eab03d0eef6b" integrity sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw== -warning@^4.0.3: +warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== From 1939238f445a8e0e98c059177f15eeb1675f642a Mon Sep 17 00:00:00 2001 From: Amelia Wattenberger Date: Wed, 20 Apr 2022 12:43:59 -0700 Subject: [PATCH 2/2] drop log --- src/blocks/file-blocks/edit/index.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/blocks/file-blocks/edit/index.tsx b/src/blocks/file-blocks/edit/index.tsx index 27056c6..ed7cc40 100644 --- a/src/blocks/file-blocks/edit/index.tsx +++ b/src/blocks/file-blocks/edit/index.tsx @@ -126,7 +126,6 @@ const syntaxHighlighterLanguageMap = { } as Record; const HunkComponent = ({ hunk, language }: { hunk: any; language: string }) => { - console.log(hunk); return (
       {hunk.changes.map((change: Hunk["change"], i: number) => (