@@ -25,7 +25,12 @@ const RefList = styled.div`
2525 gap: 5px;
2626` ;
2727
28- const GameLink = styled ( Link ) < { $status : "identical" | "differs" } > `
28+ type DiffStatus = "identical" | "offsets_only" | "differs" ;
29+
30+ const statusColor = ( status : DiffStatus ) =>
31+ status === "identical" ? "#4a8c2a" : status === "offsets_only" ? "#5b8ab5" : "#c97a1e" ;
32+
33+ const GameLink = styled ( Link ) < { $status : DiffStatus } > `
2934 display: inline-flex;
3035 align-items: center;
3136 gap: 6px;
@@ -35,34 +40,36 @@ const GameLink = styled(Link)<{ $status: "identical" | "differs" }>`
3540 text-decoration: none;
3641 color: ${ ( props ) => props . theme . text } ;
3742 background: ${ ( props ) => props . theme . groupMembers } ;
38- border: 1px solid ${ ( props ) => props . $status === "identical" ? props . theme . groupBorder : "#c97a1e" } ;
43+ border: 1px solid ${ ( props ) => props . $status === "identical" ? props . theme . groupBorder : statusColor ( props . $status ) } ;
3944 transition: border-color 0.1s;
4045
4146 &:hover {
4247 border-color: ${ ( props ) => props . theme . highlight } ;
4348 }
4449` ;
4550
46- const StatusDot = styled . span < { $status : "identical" | "differs" } > `
51+ const StatusDot = styled . span < { $status : DiffStatus } > `
4752 width: 8px;
4853 height: 8px;
4954 border-radius: 50%;
50- background-color: ${ ( props ) => props . $status === "identical" ? "#4a8c2a" : "#c97a1e" } ;
55+ background-color: ${ ( props ) => statusColor ( props . $status ) } ;
5156 flex-shrink: 0;
5257` ;
5358
54- function areClassesEqual ( a : SchemaClass , b : SchemaClass ) : boolean {
55- if ( a . parents . length !== b . parents . length ) return false ;
59+ function compareClasses ( a : SchemaClass , b : SchemaClass ) : DiffStatus {
60+ if ( a . parents . length !== b . parents . length ) return "differs" ;
5661 for ( let i = 0 ; i < a . parents . length ; i ++ ) {
57- if ( a . parents [ i ] . name !== b . parents [ i ] . name || a . parents [ i ] . module !== b . parents [ i ] . module ) return false ;
62+ if ( a . parents [ i ] . name !== b . parents [ i ] . name || a . parents [ i ] . module !== b . parents [ i ] . module ) return "differs" ;
5863 }
59- if ( a . fields . length !== b . fields . length ) return false ;
64+ if ( a . fields . length !== b . fields . length ) return "differs" ;
65+ let offsetsDiffer = false ;
6066 for ( let i = 0 ; i < a . fields . length ; i ++ ) {
61- if ( a . fields [ i ] . name !== b . fields [ i ] . name || a . fields [ i ] . offset !== b . fields [ i ] . offset ) return false ;
62- if ( JSON . stringify ( a . fields [ i ] . type ) !== JSON . stringify ( b . fields [ i ] . type ) ) return false ;
67+ if ( a . fields [ i ] . name !== b . fields [ i ] . name ) return "differs" ;
68+ if ( JSON . stringify ( a . fields [ i ] . type ) !== JSON . stringify ( b . fields [ i ] . type ) ) return "differs" ;
69+ if ( a . fields [ i ] . offset !== b . fields [ i ] . offset ) offsetsDiffer = true ;
6370 }
64- if ( JSON . stringify ( a . metadata ) !== JSON . stringify ( b . metadata ) ) return false ;
65- return true ;
71+ if ( JSON . stringify ( a . metadata ) !== JSON . stringify ( b . metadata ) ) return "differs" ;
72+ return offsetsDiffer ? "offsets_only" : "identical" ;
6673}
6774
6875function areEnumsEqual ( a : SchemaEnum , b : SchemaEnum ) : boolean {
@@ -75,11 +82,11 @@ function areEnumsEqual(a: SchemaEnum, b: SchemaEnum): boolean {
7582 return true ;
7683}
7784
78- function areDeclarationsEqual ( a : Declaration , b : Declaration ) : boolean {
79- if ( a . kind !== b . kind ) return false ;
80- if ( a . kind === "class" && b . kind === "class" ) return areClassesEqual ( a , b ) ;
81- if ( a . kind === "enum" && b . kind === "enum" ) return areEnumsEqual ( a , b ) ;
82- return false ;
85+ function compareDeclarations ( a : Declaration , b : Declaration ) : DiffStatus {
86+ if ( a . kind !== b . kind ) return "differs" ;
87+ if ( a . kind === "class" && b . kind === "class" ) return compareClasses ( a , b ) ;
88+ if ( a . kind === "enum" && b . kind === "enum" ) return areEnumsEqual ( a , b ) ? "identical" : "differs" ;
89+ return "differs" ;
8390}
8491
8592export function CrossGameRefs ( { name, module, kind } : { name : string ; module : string ; kind : "class" | "enum" } ) {
@@ -89,7 +96,7 @@ export function CrossGameRefs({ name, module, kind }: { name: string; module: st
8996 const current = declarations . find ( ( d ) => d . name === name && d . module === module && d . kind === kind ) ;
9097 if ( ! current ) return null ;
9198
92- const otherGames : { gameId : GameId ; gameName : string ; status : "identical" | "differs" ; module : string } [ ] = [ ] ;
99+ const otherGames : { gameId : GameId ; gameName : string ; status : DiffStatus ; module : string } [ ] = [ ] ;
93100
94101 for ( const [ gameId , gameDeclarations ] of allGames ) {
95102 if ( gameId === game ) continue ;
@@ -99,7 +106,7 @@ export function CrossGameRefs({ name, module, kind }: { name: string; module: st
99106 otherGames . push ( {
100107 gameId,
101108 gameName : gameInfo ?. name ?? gameId ,
102- status : areDeclarationsEqual ( current , match ) ? "identical" : "differs" ,
109+ status : compareDeclarations ( current , match ) ,
103110 module : match . module ,
104111 } ) ;
105112 }
@@ -112,7 +119,7 @@ export function CrossGameRefs({ name, module, kind }: { name: string; module: st
112119 < Title > Also in</ Title >
113120 < RefList >
114121 { otherGames . map ( ( { gameId, gameName, status, module : otherModule } ) => (
115- < GameLink key = { gameId } to = { `/${ gameId } /${ otherModule } /${ name } ` } $status = { status } title = { status === "identical" ? "Identical" : "Differs" } >
122+ < GameLink key = { gameId } to = { `/${ gameId } /${ otherModule } /${ name } ` } $status = { status } title = { status === "identical" ? "Identical" : status === "offsets_only" ? "Only offsets differ" : "Differs" } >
116123 < StatusDot $status = { status } />
117124 { gameName }
118125 </ GameLink >
0 commit comments