diff --git a/frontend/src/components/Diff/Diff.module.scss b/frontend/src/components/Diff/Diff.module.scss index 3b2d34bb..71b3b1dc 100644 --- a/frontend/src/components/Diff/Diff.module.scss +++ b/frontend/src/components/Diff/Diff.module.scss @@ -181,3 +181,20 @@ .highlightable { cursor: pointer; } + +.copyButton { + cursor: pointer; + border-radius: 4px; + width: 2em; + height: 2em; + + &:hover { + background-color: var(--a50); + } +} + +.copyButton svg { + width: 1em; + height: 1em; + display: grid; +} diff --git a/frontend/src/components/Diff/Diff.tsx b/frontend/src/components/Diff/Diff.tsx index d03bcf96..928d39af 100644 --- a/frontend/src/components/Diff/Diff.tsx +++ b/frontend/src/components/Diff/Diff.tsx @@ -2,7 +2,7 @@ import { createContext, CSSProperties, forwardRef, HTMLAttributes, MutableRefObject, useRef, useState } from "react" -import { VersionsIcon } from "@primer/octicons-react" +import { VersionsIcon, CopyIcon } from "@primer/octicons-react" import { EditorView } from "codemirror" import { DiffResult } from "objdiff-wasm" import AutoSizer from "react-virtualized-auto-sizer" @@ -20,6 +20,36 @@ import * as Objdiff from "./DiffRowObjdiff" import DragBar from "./DragBar" import { useHighlighers } from "./Highlighter" +const copyDiffContentsToClipboard = (diff: api.DiffOutput, kind: string) => { + // kind is either "base", "current", or "previous" + const contents = diff.rows.map(row => { + let text = "" + if (kind === "base" && row.base) { + text = row.base.text.map(t => t.text).join("") + } else if (kind === "current" && row.current) { + text = row.current.text.map(t => t.text).join("") + } else if (kind === "previous" && row.previous) { + text = row.previous.text.map(t => t.text).join("") + } + return text + }) + + navigator.clipboard.writeText(contents.join("\n")) +} + +// Small component for the copy button +function CopyButton({ diff, kind }: { diff: api.DiffOutput, kind: string }) { + return ( + copyDiffContentsToClipboard(diff, kind)} + title="Copy content" + > + + + ) +} + // https://github.com/bvaughn/react-window#can-i-add-padding-to-the-top-and-bottom-of-a-list const innerElementType = forwardRef>(({ style, ...rest }, ref) => { return Target + Current + {isCompiling && } {!threeWayDiffEnabled && threeWayButton} {threeWayDiffEnabled && {threeWayDiffBase === ThreeWayDiffBase.SAVED ? "Saved" : "Previous"} + {threeWayButton} }