1
+ import cx from 'classnames'
1
2
import * as React from 'react'
2
- import ReactDiffViewer from 'react-diff-viewer-continued'
3
3
import * as M from '@material-ui/core'
4
+ import { diffJson , ChangeObject } from 'diff'
4
5
6
+ import assertNever from 'utils/assertNever'
5
7
import Skeleton from 'components/Skeleton'
6
8
7
- import type { RevisionResult } from '../useRevision'
9
+ import type { Revision , RevisionResult } from '../useRevision'
10
+
11
+ import Change from './Change'
12
+ import type { Dir } from './Change'
13
+ import GridRow from './GridRow'
8
14
9
15
interface MetadataDiffProps {
10
16
left : RevisionResult
11
17
right : RevisionResult
12
18
}
13
19
20
+ interface ChangeLineProps {
21
+ change : ChangeObject < string >
22
+ dir : Dir
23
+ }
24
+
25
+ function ChangeLine ( { change : { added, removed, value } , dir } : ChangeLineProps ) {
26
+ const order = React . useMemo ( ( ) => {
27
+ if ( ! added && ! removed ) return 'limbo'
28
+ switch ( dir ) {
29
+ case 'forward' :
30
+ if ( added ) return 'latter'
31
+ return 'former'
32
+ case 'backward' :
33
+ if ( added ) return 'former'
34
+ return 'latter'
35
+ default :
36
+ assertNever ( dir )
37
+ }
38
+ } , [ added , removed , dir ] )
39
+ return (
40
+ < Change order = { order } >
41
+ < pre > { value } </ pre >
42
+ </ Change >
43
+ )
44
+ }
45
+
46
+ const useStyles = M . makeStyles ( ( t ) => ( {
47
+ row : {
48
+ borderBottom : `1px solid ${ t . palette . divider } ` ,
49
+ '&:last-child' : {
50
+ borderBottom : 'none' ,
51
+ } ,
52
+ } ,
53
+ head : {
54
+ background : t . palette . background . default ,
55
+ ...t . typography . caption ,
56
+ } ,
57
+ empty : {
58
+ ...t . typography . body2 ,
59
+ color : t . palette . text . secondary ,
60
+ fontStyle : 'italic' ,
61
+ textAlign : 'center' ,
62
+ padding : t . spacing ( 2 ) ,
63
+ } ,
64
+ } ) )
65
+
66
+ function MetadataDiffComponent ( { left, right } : { left : Revision ; right : Revision } ) {
67
+ const classes = useStyles ( )
68
+
69
+ const dir : Dir = React . useMemo (
70
+ ( ) => ( left . modified > right . modified ? 'backward' : 'forward' ) ,
71
+ [ left . modified , right . modified ] ,
72
+ )
73
+
74
+ const changes = React . useMemo (
75
+ ( ) => diffJson ( left . userMeta || { } , right . userMeta || { } ) ,
76
+ [ left . userMeta , right . userMeta ] ,
77
+ )
78
+
79
+ if ( changes . length === 0 ) {
80
+ return (
81
+ < M . Typography variant = "body2" color = "textSecondary" className = { classes . empty } >
82
+ Metadata is identical
83
+ </ M . Typography >
84
+ )
85
+ }
86
+
87
+ return (
88
+ < div >
89
+ < GridRow className = { cx ( classes . row , classes . head ) } dense divided >
90
+ { left . hash }
91
+ { right . hash }
92
+ </ GridRow >
93
+ { changes . map ( ( change , index ) => (
94
+ < ChangeLine key = { index } change = { change } dir = { dir } />
95
+ ) ) }
96
+ </ div >
97
+ )
98
+ }
99
+
14
100
export default function MetadataDiff ( { left : left , right : right } : MetadataDiffProps ) {
15
101
if ( left . _tag === 'idle' || right . _tag === 'idle' ) {
16
102
return null
@@ -28,33 +114,5 @@ export default function MetadataDiff({ left: left, right: right }: MetadataDiffP
28
114
)
29
115
}
30
116
31
- const leftMetadata = left . revision . userMeta || { }
32
- const rightMetadata = right . revision . userMeta || { }
33
-
34
- const leftMetadataString = JSON . stringify ( leftMetadata , null , 2 )
35
- const rightMetadataString = JSON . stringify ( rightMetadata , null , 2 )
36
-
37
- if ( leftMetadataString === rightMetadataString ) {
38
- return (
39
- < M . Typography
40
- variant = "body2"
41
- color = "textSecondary"
42
- style = { { fontStyle : 'italic' , textAlign : 'center' , padding : 16 } }
43
- >
44
- Metadata is identical
45
- </ M . Typography >
46
- )
47
- }
48
-
49
- return (
50
- < ReactDiffViewer
51
- oldValue = { leftMetadataString }
52
- newValue = { rightMetadataString }
53
- splitView = { true }
54
- leftTitle = { left . revision . hash }
55
- rightTitle = { right . revision . hash }
56
- showDiffOnly
57
- hideLineNumbers = { false }
58
- />
59
- )
117
+ return < MetadataDiffComponent left = { left . revision } right = { right . revision } />
60
118
}
0 commit comments