From ed3444c2f0dd3b5c68f624cda2d74bb1d1157ec6 Mon Sep 17 00:00:00 2001 From: Jerel Miller Date: Wed, 14 Oct 2020 03:00:58 -0700 Subject: [PATCH] feat: handle proper diffing on each step --- src/components/Tutorial.js | 13 ++++--- src/components/TutorialEditor.js | 62 ++++++++++++++++++++------------ src/components/TutorialStep.js | 6 ++-- 3 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/components/Tutorial.js b/src/components/Tutorial.js index edd5848f7..2503d5c1e 100644 --- a/src/components/Tutorial.js +++ b/src/components/Tutorial.js @@ -34,17 +34,16 @@ const Tutorial = ({ children }) => { .find(Boolean) || initialState ); - const { fileName, code, language } = parseCodeBlockProps(codeBlock); - const { code: prevCode } = previousStep.get(fileName); + const props = parseCodeBlockProps(codeBlock); + const { code: prevCode } = previousStep.get(props.fileName); return [ ...steps, cloneElement(stepElement, { - initialSelectedFile: fileName, - step: previousStep.set(fileName, { - code, - language, - diff: diffLines(prevCode, code), + codeBlock: { ...props, diff: diffLines(prevCode, props.code) }, + step: previousStep.set(props.fileName, { + code: props.code, + language: props.language, }), index: idx, totalSteps: arr.length, diff --git a/src/components/TutorialEditor.js b/src/components/TutorialEditor.js index b56815d5e..4fe809ecb 100644 --- a/src/components/TutorialEditor.js +++ b/src/components/TutorialEditor.js @@ -5,31 +5,47 @@ import path from 'path'; import { css } from '@emotion/core'; import { darken } from 'polished'; -const TutorialEditor = ({ initialSelectedFile, files }) => { - const [selectedFile, setSelectedFile] = useState(initialSelectedFile); - const { diff } = files.get(selectedFile); +const last = (arr) => arr[arr.length - 1]; - const [highlightedLines] = diff.reduce( - ([highlightedLines, lineNumber], change) => { - const { count, added, removed } = change; - // Include current line when counting the end of the range - const rangeEnd = lineNumber + count - 1; +const diffHighlightedLines = (diff) => { + const { highlightedLines } = diff.reduce( + ({ highlightedLines, currentLineNumber }, change) => { + const { count, added, removed, value } = change; - return [ - added - ? [ - ...highlightedLines, - lineNumber === rangeEnd - ? lineNumber - : `${lineNumber}-${lineNumber + count - 1}`, - ] - : highlightedLines, - removed ? lineNumber : lineNumber + count, - ]; + if (!added) { + return { + highlightedLines, + currentLineNumber: removed + ? currentLineNumber + : currentLineNumber + count, + }; + } + + const lines = value.split('\n').slice(0, count); + + // Don't highlight the last line if the last line is blank. Subtract at + // least 1 because we want to include the current line in the range. + const subtractAmount = last(lines) === '' ? 2 : 1; + const rangeEnd = currentLineNumber + count - subtractAmount; + const range = + currentLineNumber === rangeEnd + ? currentLineNumber + : `${currentLineNumber}-${rangeEnd}`; + + return { + highlightedLines: [...highlightedLines, range], + currentLineNumber: currentLineNumber + count, + }; }, - [[], 1] + { highlightedLines: [], currentLineNumber: 1 } ); + return highlightedLines.join(','); +}; + +const TutorialEditor = ({ codeBlock, files }) => { + const [selectedFile, setSelectedFile] = useState(codeBlock.fileName); + return (
{ language={language} fileName={fileName} highlightedLines={ - fileName === selectedFile ? highlightedLines.join(',') : null + fileName === codeBlock.fileName && codeBlock.diff + ? diffHighlightedLines(codeBlock.diff) + : null } css={css` display: ${fileName === selectedFile ? 'block' : 'none'}; @@ -88,7 +106,7 @@ const TutorialEditor = ({ initialSelectedFile, files }) => { }; TutorialEditor.propTypes = { - initialSelectedFile: PropTypes.string.isRequired, + codeBlock: PropTypes.object.isRequired, files: PropTypes.instanceOf(Map).isRequired, }; diff --git a/src/components/TutorialStep.js b/src/components/TutorialStep.js index 07d88522b..8a85cbe71 100644 --- a/src/components/TutorialStep.js +++ b/src/components/TutorialStep.js @@ -6,6 +6,7 @@ import Markdown from './Markdown'; const TutorialStep = ({ children, + codeBlock, initialSelectedFile, step, index, @@ -47,10 +48,7 @@ const TutorialStep = ({ `} >
{children}
- +
) : ( children