Skip to content

Commit 008194d

Browse files
committed
comments feature, fix vulnerabilities
1 parent 9ac4ba9 commit 008194d

12 files changed

+12732
-1300
lines changed

.eslintrc

+19-6
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,24 @@
22
"extends": ["airbnb-base", "plugin:@typescript-eslint/recommended"],
33
"rules": {
44
"no-tabs": "off",
5-
"@typescript-eslint/indent": ["error", 2],
6-
"max-len": ["error", {
7-
"code": 100
8-
}],
95
"arrow-body-style": "off",
6+
"comma-dangle": "off",
7+
"@typescript-eslint/no-var-requires": 0,
8+
"operator-linebreak": "off",
9+
"@typescript-eslint/no-explicit-any": 0,
10+
"@typescript-eslint/explicit-function-return-type": 0,
11+
"implicit-arrow-linebreak": "off",
12+
"@typescript-eslint/indent": 0,
13+
"import/extensions": [
14+
"error",
15+
"ignorePackages",
16+
{
17+
"ts": "never",
18+
"js": "never",
19+
"mjs": "never",
20+
"jsx": "never"
21+
}
22+
]
1023
},
1124
"settings": {
1225
"import/resolver": {
@@ -18,6 +31,6 @@
1831
"env": {
1932
"mocha": true,
2033
"node": true,
21-
"browser": true,
22-
},
34+
"browser": true
35+
}
2336
}

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
node_modules
22
dist
33
lib
4-
*.log
4+
*.log

examples/src/CommentBlock.tsx

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import * as React from 'react';
2+
import { CommentInfo } from '../../lib';
3+
4+
interface Props {
5+
updateComment: (commentInfo: CommentInfo, text: string) => void;
6+
removeComment: (lineId: string) => void;
7+
comment: any;
8+
show: boolean;
9+
}
10+
11+
const CommentBlock: React.FC<Props> = ({
12+
updateComment,
13+
removeComment,
14+
comment,
15+
show
16+
}) => {
17+
const [isComment, setIsComment] = React.useState<boolean>(show);
18+
const [text, setText] = React.useState<string>(
19+
comment.body ? comment.body.text : ''
20+
);
21+
22+
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
23+
setText(e.target.value);
24+
};
25+
26+
if (!isComment) {
27+
return (
28+
<div className='p-2'>
29+
<div className='form-group mb-2'>
30+
<textarea
31+
onChange={handleChange}
32+
value={text}
33+
className='form-control'
34+
/>
35+
</div>
36+
<button
37+
className='btn btn-primary mr-2'
38+
onClick={() => {
39+
if (!text) {
40+
return removeComment(comment.lineId);
41+
}
42+
updateComment(comment, text);
43+
setIsComment(true);
44+
}}
45+
>
46+
Submit
47+
</button>
48+
<button
49+
className='btn btn-secondary'
50+
onClick={() => {
51+
if (!text) {
52+
return removeComment(comment.lineId);
53+
}
54+
setIsComment(true);
55+
}}
56+
>
57+
Cancel
58+
</button>
59+
</div>
60+
);
61+
}
62+
return (
63+
<div className='p-2'>
64+
<div className='mb-2 bg-light rounded p-2'>
65+
{comment.body.text &&
66+
comment.body.text
67+
.split('\n')
68+
.map((str: string, i: number) => <div key={i}>{str}</div>)}
69+
</div>
70+
<button
71+
onClick={() => setIsComment(false)}
72+
className='btn btn-primary mr-2'
73+
>
74+
Edit
75+
</button>
76+
<button
77+
onClick={() => removeComment(comment.lineId)}
78+
className='btn btn-secondary mr-2'
79+
>
80+
Delete
81+
</button>
82+
</div>
83+
);
84+
};
85+
86+
export default CommentBlock;

examples/src/index.tsx

+113-26
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
require('./style.scss');
21
import * as React from 'react';
32
import * as ReactDOM from 'react-dom';
4-
53
import ReactDiff, { DiffMethod } from '../../lib/index';
6-
4+
import CommentBlock from './CommentBlock';
5+
import { CommentInfo } from '../../lib/index';
76
const oldJs = require('./diff/javascript/old.rjs').default;
87
const newJs = require('./diff/javascript/new.rjs').default;
9-
108
const logo = require('../../logo.png');
9+
require('./style.scss');
1110

1211
interface ExampleState {
1312
splitView?: boolean;
1413
highlightLine?: string[];
1514
language?: string;
1615
enableSyntaxHighlighting?: boolean;
1716
compareMethod?: DiffMethod;
17+
comments: any[];
1818
}
1919

2020
const P = (window as any).Prism;
@@ -25,13 +25,27 @@ class Example extends React.Component<{}, ExampleState> {
2525
this.state = {
2626
highlightLine: [],
2727
enableSyntaxHighlighting: true,
28+
comments: [
29+
{
30+
body: {
31+
lineId: 'L-12-beforeCommit-afterCommit-test/test.jsx',
32+
text: 'Awesome\ncomment!',
33+
fileId: 'test/test.jsx',
34+
prefix: 'L',
35+
lineNumber: 12,
36+
specifier: 'beforeCommit-afterCommit'
37+
}
38+
}
39+
]
2840
};
2941
}
3042

3143
private onLineNumberClick = (
3244
id: string,
33-
e: React.MouseEvent<HTMLTableCellElement>,
45+
uiniqueLindeId: string,
46+
e: React.MouseEvent<HTMLTableCellElement>
3447
): void => {
48+
console.log(uiniqueLindeId);
3549
let highlightLine = [id];
3650
if (e.shiftKey && this.state.highlightLine.length === 1) {
3751
const [dir, oldId] = this.state.highlightLine[0].split('-');
@@ -46,45 +60,99 @@ class Example extends React.Component<{}, ExampleState> {
4660
}
4761
}
4862
this.setState({
49-
highlightLine,
63+
highlightLine
5064
});
5165
};
5266

53-
private syntaxHighlight = (str: string): any => {
54-
if (!str) return;
55-
const language = P.highlight(str, P.languages.javascript);
56-
return <span dangerouslySetInnerHTML={{ __html: language }} />;
67+
private syntaxHighlight = (source: string, lineId?: string): any => {
68+
if (!source) return;
69+
const language = P.highlight(source, P.languages.javascript);
70+
return <span id={lineId} dangerouslySetInnerHTML={{ __html: language }} />;
5771
};
5872

59-
public render(): JSX.Element {
73+
private updateComment = (commentInfo: any, text?: string) => {
74+
const updatedComments = this.state.comments.map(comment => {
75+
console.log(comment);
76+
if (comment.lineId === commentInfo.lineId) {
77+
return {
78+
...commentInfo,
79+
lineId: commentInfo.uniqueLineId,
80+
body: text
81+
};
82+
}
83+
return comment;
84+
});
85+
86+
this.setState({
87+
comments: updatedComments
88+
});
89+
};
90+
91+
private removeComment = (lineId: string) => {
92+
const updatedComments = this.state.comments.filter(
93+
comment => comment.lineId !== lineId
94+
);
95+
this.setState({ comments: updatedComments });
96+
};
97+
98+
private createComment = (commentInfo: CommentInfo) => {
99+
const updatedComments = [
100+
...this.state.comments,
101+
{
102+
body: {
103+
...commentInfo,
104+
lineId: commentInfo.lineId,
105+
text: ''
106+
}
107+
}
108+
];
109+
this.setState({ comments: updatedComments });
110+
};
111+
112+
/**
113+
*
114+
* helper that return Array with uniqueLineIds (comment.lineId)
115+
*
116+
* @param arr Array with commentLineIds
117+
*
118+
*/
60119

120+
private getlineIdsArray = (arr: any[]) => {
121+
return arr.reduce((acc: Array<string>, comment) => {
122+
acc.push(comment.body.lineId);
123+
return acc;
124+
}, []);
125+
};
126+
127+
public render(): JSX.Element {
61128
return (
62-
<div className="react-diff-viewer-example">
63-
<div className="radial"></div>
64-
<div className="banner">
65-
<div className="img-container">
66-
<img src={logo} alt="React Diff Viewer Logo" />
129+
<div className='react-diff-viewer-example'>
130+
<div className='radial'></div>
131+
<div className='banner'>
132+
<div className='img-container'>
133+
<img src={logo} alt='React Diff Viewer Logo' />
67134
</div>
68135
<p>
69136
A simple and beautiful text diff viewer made with{' '}
70-
<a href="https://github.com/kpdecker/jsdiff" target="_blank">
137+
<a href='https://github.com/kpdecker/jsdiff' target='_blank'>
71138
Diff{' '}
72139
</a>
73140
and{' '}
74-
<a href="https://reactjs.org" target="_blank">
141+
<a href='https://reactjs.org' target='_blank'>
75142
React.{' '}
76143
</a>
77-
Featuring split view, inline view, word diff, line highlight and more.
144+
Featuring split view, inline view, word diff, line highlight and
145+
more.
78146
</p>
79-
<div className="cta">
80-
<a href="https://github.com/praneshr/react-diff-viewer#install">
81-
<button type="button" className="btn btn-primary btn-lg">
147+
<div className='cta'>
148+
<a href='https://github.com/praneshr/react-diff-viewer#install'>
149+
<button type='button' className='btn btn-primary btn-lg'>
82150
Documentation
83151
</button>
84152
</a>
85153
</div>
86154
</div>
87-
<div className="diff-viewer">
155+
<div className='diff-viewer'>
88156
<ReactDiff
89157
highlightLines={this.state.highlightLine}
90158
onLineNumberClick={this.onLineNumberClick}
@@ -93,13 +161,32 @@ class Example extends React.Component<{}, ExampleState> {
93161
newValue={newJs}
94162
renderContent={this.syntaxHighlight}
95163
useDarkTheme
96-
leftTitle="webpack.config.js master@2178133 - pushed 2 hours ago."
97-
rightTitle="webpack.config.js master@64207ee - pushed 13 hours ago."
164+
leftTitle='webpack.config.js master@2178133 - pushed 2 hours ago.'
165+
rightTitle='webpack.config.js master@64207ee - pushed 13 hours ago.'
166+
afterCommit={'afterCommit'}
167+
beforeCommit={'beforeCommit'}
168+
commentLineIds={this.getlineIdsArray(this.state.comments)}
169+
getCommentInfo={commentInfo => this.createComment(commentInfo)}
170+
renderCommentBlock={commentInfo => {
171+
console.log(commentInfo);
172+
const currComment = this.state.comments.find(
173+
comment => comment.body.lineId === commentInfo.lineId
174+
);
175+
return (
176+
<CommentBlock
177+
updateComment={this.updateComment}
178+
removeComment={this.removeComment}
179+
comment={currComment}
180+
show={!!currComment.body.text}
181+
/>
182+
);
183+
}}
184+
fileId={'test/test.jsx'}
98185
/>
99186
</div>
100187
<footer>
101188
Made with 💓 by{' '}
102-
<a href="https://praneshravi.in" target="_blank">
189+
<a href='https://praneshravi.in' target='_blank'>
103190
Pranesh Ravi
104191
</a>
105192
</footer>

0 commit comments

Comments
 (0)