diff options
| author | Nate Sesti <sestinj@gmail.com> | 2023-05-23 23:45:12 -0400 | 
|---|---|---|
| committer | Nate Sesti <sestinj@gmail.com> | 2023-05-23 23:45:12 -0400 | 
| commit | f53768612b1e2268697b5444e502032ef9f3fb3c (patch) | |
| tree | 4ed49b73e6bd3c2f8fceffa9643973033f87af95 /extension/react-app/src/components/CodeMultiselect.tsx | |
| download | sncontinue-f53768612b1e2268697b5444e502032ef9f3fb3c.tar.gz sncontinue-f53768612b1e2268697b5444e502032ef9f3fb3c.tar.bz2 sncontinue-f53768612b1e2268697b5444e502032ef9f3fb3c.zip | |
copying from old repo
Diffstat (limited to 'extension/react-app/src/components/CodeMultiselect.tsx')
| -rw-r--r-- | extension/react-app/src/components/CodeMultiselect.tsx | 276 | 
1 files changed, 276 insertions, 0 deletions
| diff --git a/extension/react-app/src/components/CodeMultiselect.tsx b/extension/react-app/src/components/CodeMultiselect.tsx new file mode 100644 index 00000000..626ae42f --- /dev/null +++ b/extension/react-app/src/components/CodeMultiselect.tsx @@ -0,0 +1,276 @@ +import React, { useEffect, useState } from "react"; +import styled from "styled-components"; +import { Button, buttonColor, defaultBorderRadius, secondaryDark } from "."; +import { useSelector } from "react-redux"; +import { +  selectDebugContext, +  selectAllRangesInFiles, +  selectRangesMask, +} from "../redux/selectors/debugContextSelectors"; +import "../highlight/dark.min.css"; +import hljs from "highlight.js"; +import { postVscMessage } from "../vscode"; +import { RootStore } from "../redux/store"; +import { useDispatch } from "react-redux"; +import { +  addRangeInFile, +  deleteRangeInFileAt, +  toggleSelectionAt, +  updateFileSystem, +} from "../redux/slices/debugContexSlice"; +import { RangeInFile } from "../../../src/client"; +import { readRangeInVirtualFileSystem } from "../util"; + +//#region Styled Components + +const MultiSelectContainer = styled.div` +  border-radius: ${defaultBorderRadius}; +  padding: 4px; +  display: flex; +  flex-direction: column; +  gap: 4px; +`; + +const MultiSelectHeader = styled.div` +  display: flex; +  justify-content: space-between; +  align-items: left; +  border-bottom: 1px solid gray; +  padding-left: 4px; +  padding-right: 4px; +  & p { +    overflow-wrap: break-word; +    word-wrap: break-word; +    -ms-wrap-flow: break-word; +    overflow: hidden; +  } +`; + +const MultiSelectOption = styled.div` +  border-radius: ${defaultBorderRadius}; +  padding-top: 4px; +  cursor: pointer; +  background-color: ${secondaryDark}; +`; + +const DeleteSelectedRangeButton = styled(Button)` +  align-self: right; +  padding: 0px; +  margin-top: 0; +  aspect-ratio: 1/1; +  height: 28px; +`; + +const ToggleHighlightButton = styled(Button)` +  display: grid; +  justify-content: center; +  align-items: center; +  grid-template-columns: 30px 1fr; +  margin-left: 20px; +  order: 1; +  width: fit-content; +`; + +//#endregion + +//#region Path Formatting + +const filenameToLanguageMap: any = { +  py: "python", +  js: "javascript", +  ts: "typescript", +  html: "html", +  css: "css", +  java: "java", +  c: "c", +  cpp: "cpp", +  cs: "csharp", +  go: "go", +  rb: "ruby", +  rs: "rust", +  swift: "swift", +  php: "php", +  scala: "scala", +  kt: "kotlin", +  dart: "dart", +  hs: "haskell", +  lua: "lua", +  pl: "perl", +  r: "r", +  sql: "sql", +  vb: "vb", +  xml: "xml", +  yaml: "yaml", +}; + +function filenameToLanguage(filename: string): string { +  const extension = filename.split(".").pop(); +  if (extension === undefined) { +    return ""; +  } +  return filenameToLanguageMap[extension] || ""; +} + +function formatPathRelativeToWorkspace( +  path: string, +  workspacePath: string | undefined +) { +  if (workspacePath === undefined) { +    return path; +  } +  if (path.startsWith(workspacePath)) { +    return path.substring(workspacePath.length + 1); +  } else { +    return path; +  } +} + +function formatFileRange( +  rangeInFile: RangeInFile, +  workspacePath: string | undefined +) { +  return `${formatPathRelativeToWorkspace( +    rangeInFile.filepath, +    workspacePath +  )} (lines ${rangeInFile.range.start.line + 1}-${ +    rangeInFile.range.end.line + 1 +  })`; +  // +1 because VSCode Ranges are 0-indexed +} + +//#endregion + +function CodeMultiselect(props: {}) { +  // State +  const [highlightLocked, setHighlightLocked] = useState(true); + +  // Redux +  const dispatch = useDispatch(); +  const workspacePath = useSelector( +    (state: RootStore) => state.config.workspacePath +  ); +  const debugContext = useSelector(selectDebugContext); +  const rangesInFiles = useSelector(selectAllRangesInFiles); +  const rangesInFilesMask = useSelector(selectRangesMask); + +  useEffect(() => { +    let eventListener = (event: any) => { +      switch (event.data.type) { +        case "highlightedCode": +          if (!highlightLocked) { +            dispatch( +              addRangeInFile({ +                rangeInFile: event.data.rangeInFile, +                canUpdateLast: true, +              }) +            ); +            dispatch(updateFileSystem(event.data.filesystem)); +          } +          break; +        case "findSuspiciousCode": +          for (let c of event.data.codeLocations) { +            dispatch(addRangeInFile({ rangeInFile: c, canUpdateLast: false })); +          } +          dispatch(updateFileSystem(event.data.filesystem)); +          postVscMessage("listTenThings", { debugContext }); +          break; +      } +    }; +    window.addEventListener("message", eventListener); +    return () => window.removeEventListener("message", eventListener); +  }, [debugContext, highlightLocked]); + +  useEffect(() => { +    hljs.highlightAll(); +  }, [rangesInFiles]); + +  return ( +    <MultiSelectContainer> +      {rangesInFiles.map((range: RangeInFile, index: number) => { +        return ( +          <MultiSelectOption +            key={index} +            style={{ +              border: `1px solid ${ +                rangesInFilesMask[index] ? buttonColor : "gray" +              }`, +            }} +            onClick={() => { +              dispatch(toggleSelectionAt(index)); +            }} +          > +            <MultiSelectHeader> +              <p style={{ margin: "4px" }}> +                {formatFileRange(range, workspacePath)} +              </p> +              <DeleteSelectedRangeButton +                onClick={() => dispatch(deleteRangeInFileAt(index))} +              > +                x +              </DeleteSelectedRangeButton> +            </MultiSelectHeader> +            <pre> +              <code +                className={"language-" + filenameToLanguage(range.filepath)} +              > +                {readRangeInVirtualFileSystem(range, debugContext.filesystem)} +              </code> +            </pre> +          </MultiSelectOption> +        ); +      })} +      {rangesInFiles.length === 0 && ( +        <> +          <p>Highlight relevant code in the editor.</p> +        </> +      )} +      <ToggleHighlightButton +        onClick={() => { +          setHighlightLocked(!highlightLocked); +        }} +      > +        {highlightLocked ? ( +          <> +            <svg +              xmlns="http://www.w3.org/2000/svg" +              width="20px" +              fill="none" +              viewBox="0 0 24 24" +              strokeWidth="1.5" +              stroke="currentColor" +              className="w-6 h-6" +            > +              <path +                strokeLinecap="round" +                strokeLinejoin="round" +                d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z" +              /> +            </svg>{" "} +            Enable Highlight +          </> +        ) : ( +          <> +            <svg +              xmlns="http://www.w3.org/2000/svg" +              width="20px" +              fill="none" +              viewBox="0 0 24 24" +              strokeWidth="1.5" +              stroke="currentColor" +              className="w-6 h-6" +            > +              <path +                strokeLinecap="round" +                strokeLinejoin="round" +                d="M13.5 10.5V6.75a4.5 4.5 0 119 0v3.75M3.75 21.75h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H3.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z" +              /> +            </svg>{" "} +            Disable Highlight +          </> +        )} +      </ToggleHighlightButton> +    </MultiSelectContainer> +  ); +} + +export default CodeMultiselect; | 
