Skip to content

Commit

Permalink
feat: handle proper diffing on each step
Browse files Browse the repository at this point in the history
  • Loading branch information
jerelmiller committed Oct 14, 2020
1 parent c484371 commit ed3444c
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 33 deletions.
13 changes: 6 additions & 7 deletions src/components/Tutorial.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
62 changes: 40 additions & 22 deletions src/components/TutorialEditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<div>
<div
Expand Down Expand Up @@ -69,7 +85,9 @@ const TutorialEditor = ({ initialSelectedFile, files }) => {
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'};
Expand All @@ -88,7 +106,7 @@ const TutorialEditor = ({ initialSelectedFile, files }) => {
};

TutorialEditor.propTypes = {
initialSelectedFile: PropTypes.string.isRequired,
codeBlock: PropTypes.object.isRequired,
files: PropTypes.instanceOf(Map).isRequired,
};

Expand Down
6 changes: 2 additions & 4 deletions src/components/TutorialStep.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Markdown from './Markdown';

const TutorialStep = ({
children,
codeBlock,
initialSelectedFile,
step,
index,
Expand Down Expand Up @@ -47,10 +48,7 @@ const TutorialStep = ({
`}
>
<div>{children}</div>
<TutorialEditor
files={step}
initialSelectedFile={initialSelectedFile}
/>
<TutorialEditor codeBlock={codeBlock} files={step} />
</div>
) : (
children
Expand Down

0 comments on commit ed3444c

Please sign in to comment.