@@ -65,6 +65,8 @@ class CustomAchievements {
6565 this . _popupCloseResolve ( ) ;
6666 this . _popupCloseResolve = null ;
6767 }
68+ } else if ( data . action === 'ACHIEVEMENT_RENAMED' ) {
69+ this . _renameAchievement ( data . oldName , data . newName ) ;
6870 }
6971 }
7072 } ) ;
@@ -139,6 +141,65 @@ class CustomAchievements {
139141 }
140142 }
141143
144+ /**
145+ * Renames an achievement in the cache and updates all blocks referencing it.
146+ * @param {string } oldName The previous name of the achievement
147+ * @param {string } newName The new name of the achievement
148+ */
149+ _renameAchievement ( oldName , newName ) {
150+ if ( ! oldName || ! newName || oldName === newName ) return ;
151+
152+ // 1. Update internal cache
153+ if ( Object . prototype . hasOwnProperty . call ( this . _cache , oldName ) ) {
154+ this . _cache [ newName ] = this . _cache [ oldName ] ;
155+ delete this . _cache [ oldName ] ;
156+ }
157+
158+ // 2. Update overridden set
159+ if ( this . _overriddenAchievements . has ( oldName ) ) {
160+ this . _overriddenAchievements . delete ( oldName ) ;
161+ this . _overriddenAchievements . add ( newName ) ;
162+ }
163+
164+ // 3. Update blocks in the runtime
165+ const targets = this . runtime . targets ;
166+ for ( let i = 0 ; i < targets . length ; i ++ ) {
167+ const target = targets [ i ] ;
168+ const blocks = target . blocks ;
169+
170+ for ( const blockId in blocks . _blocks ) {
171+ if ( ! Object . prototype . hasOwnProperty . call ( blocks . _blocks , blockId ) ) continue ;
172+ const block = blocks . _blocks [ blockId ] ;
173+
174+ // Check if this is a custom achievements block
175+ if ( block . opcode . startsWith ( 'customAchievements_' ) ) {
176+ // Check inputs (for menu arguments)
177+ if ( block . inputs . ACHIEVEMENT ) {
178+ const input = block . inputs . ACHIEVEMENT ;
179+ // Usually extension menus are shadow blocks connected to the input
180+ const shadowBlockId = input . shadow ;
181+ if ( shadowBlockId ) {
182+ const shadowBlock = blocks . getBlock ( shadowBlockId ) ;
183+ if ( shadowBlock && shadowBlock . fields ) {
184+ for ( const fieldName in shadowBlock . fields ) {
185+ if ( shadowBlock . fields [ fieldName ] . value === oldName ) {
186+ shadowBlock . fields [ fieldName ] . value = newName ;
187+ }
188+ }
189+ }
190+ }
191+ }
192+ }
193+ }
194+ }
195+
196+ // 4. Refresh UI to show new name in dropdowns and blocks
197+ if ( this . runtime . extensionManager ) {
198+ this . runtime . extensionManager . refreshBlocks ( ) ;
199+ }
200+ this . runtime . requestBlocksUpdate ( ) ;
201+ }
202+
142203 /**
143204 * Fetches achievement data from the API.
144205 * @returns {Promise<void> }
0 commit comments