@@ -79,6 +79,15 @@ class ObfProcessor extends BaseProcessor {
7979 }
8080 private processBoard ( boardData : ObfBoard , _boardPath : string ) : AACPage {
8181 const sourceButtons = boardData . buttons || [ ] ;
82+
83+ // Calculate page ID first (used to make button IDs unique)
84+ const pageId =
85+ _boardPath && _boardPath . endsWith ( '.obf' ) && ! _boardPath . includes ( '/' )
86+ ? _boardPath // Zip entry - use filename to match navigation paths
87+ : boardData ?. id
88+ ? String ( boardData . id )
89+ : _boardPath ?. split ( '/' ) . pop ( ) || '' ;
90+
8291 const buttons : AACButton [ ] = sourceButtons . map ( ( btn : ObfButton ) : AACButton => {
8392 const semanticAction : AACSemanticAction = btn . load_board
8493 ? {
@@ -101,7 +110,8 @@ class ObfProcessor extends BaseProcessor {
101110 } ;
102111
103112 return new AACButton ( {
104- id : String ( btn ?. id || '' ) ,
113+ // Make button ID unique by combining page ID and button ID
114+ id : `${ pageId } ::${ btn ?. id || '' } ` ,
105115 label : String ( btn ?. label || '' ) ,
106116 message : String ( btn ?. vocalization || btn ?. label || '' ) ,
107117 visibility : mapObfVisibility ( btn . hidden ) ,
@@ -118,7 +128,7 @@ class ObfProcessor extends BaseProcessor {
118128 const buttonMap = new Map ( buttons . map ( ( btn ) => [ btn . id , btn ] ) ) ;
119129
120130 const page = new AACPage ( {
121- id : String ( boardData ?. id || '' ) ,
131+ id : pageId , // Use the page ID we calculated earlier
122132 name : String ( boardData ?. name || '' ) ,
123133 grid : [ ] ,
124134 buttons,
@@ -156,7 +166,7 @@ class ObfProcessor extends BaseProcessor {
156166 orderRow . forEach ( ( cellId , colIndex ) => {
157167 if ( cellId === null || cellId === undefined ) return ;
158168 if ( rowIndex >= rows || colIndex >= cols ) return ;
159- const aacBtn = buttonMap . get ( String ( cellId ) ) ;
169+ const aacBtn = buttonMap . get ( ` ${ pageId } :: ${ cellId } ` ) ;
160170 if ( aacBtn ) {
161171 grid [ rowIndex ] [ colIndex ] = aacBtn ;
162172 }
@@ -168,7 +178,7 @@ class ObfProcessor extends BaseProcessor {
168178 const row = Math . floor ( btn . box_id / cols ) ;
169179 const col = btn . box_id % cols ;
170180 if ( row < rows && col < cols ) {
171- const aacBtn = buttonMap . get ( String ( btn . id ) ) ;
181+ const aacBtn = buttonMap . get ( ` ${ pageId } :: ${ btn . id } ` ) ;
172182 if ( aacBtn ) {
173183 grid [ row ] [ col ] = aacBtn ;
174184 }
0 commit comments