|
class ScenesPanel { |
|
constructor() { |
|
this.scenes = new Set(); |
|
this.currentScene = null; |
|
this.container = document.querySelector('.scene-buttons'); |
|
this.clearBtn = document.querySelector('.clear-selection-btn'); |
|
this.init(); |
|
} |
|
|
|
init() { |
|
|
|
|
|
|
|
window.addEventListener('scene-update', (event) => { |
|
const sceneNumber = event.detail.scene; |
|
if (sceneNumber !== undefined) { |
|
this.addScene(sceneNumber); |
|
} |
|
}); |
|
|
|
|
|
window.addEventListener('websocket-message', (event) => { |
|
const message = event.detail; |
|
|
|
|
|
if (message.type === 'initial_data' && message.data.history_messages) { |
|
message.data.history_messages.forEach(message => this.addScene(message.scene)); |
|
} |
|
|
|
|
|
if (message.type === 'message' && message.data.scene !== undefined) { |
|
this.addScene(message.data.scene); |
|
} |
|
}); |
|
} |
|
|
|
addScene(sceneNumber) { |
|
|
|
if (!this.scenes.has(sceneNumber) && sceneNumber !== undefined) { |
|
console.log(`Adding scene ${sceneNumber}`); |
|
this.scenes.add(sceneNumber); |
|
this.renderSceneButtons(); |
|
console.log('Current scenes:', Array.from(this.scenes)); |
|
} |
|
} |
|
|
|
initEventListeners() { |
|
|
|
this.clearBtn.addEventListener('click', () => { |
|
this.clearSelection(); |
|
}); |
|
} |
|
|
|
|
|
renderSceneButtons() { |
|
this.container.innerHTML = ''; |
|
|
|
|
|
const sortedScenes = Array.from(this.scenes).sort((a, b) => a - b); |
|
|
|
sortedScenes.forEach(scene => { |
|
const button = document.createElement('button'); |
|
button.className = 'scene-btn'; |
|
if (this.currentScene === scene) { |
|
button.classList.add('active'); |
|
} |
|
button.textContent = `场景 ${scene}`; |
|
|
|
button.addEventListener('click', () => { |
|
this.selectScene(scene); |
|
}); |
|
|
|
this.container.appendChild(button); |
|
}); |
|
} |
|
|
|
selectScene(sceneNumber) { |
|
const buttons = this.container.querySelectorAll('.scene-btn'); |
|
buttons.forEach(btn => btn.classList.remove('active')); |
|
|
|
if (this.currentScene === sceneNumber) { |
|
|
|
this.currentScene = null; |
|
console.log('Scene selection cleared'); |
|
} else { |
|
|
|
this.currentScene = sceneNumber; |
|
buttons.forEach(btn => { |
|
if (btn.textContent === `场景 ${sceneNumber}`) { |
|
btn.classList.add('active'); |
|
} |
|
}); |
|
console.log('Scene selected:', sceneNumber); |
|
} |
|
|
|
|
|
window.dispatchEvent(new CustomEvent('scene-selected', { |
|
detail: { scene: this.currentScene } |
|
})); |
|
|
|
if (window.ws && window.ws.readyState === WebSocket.OPEN) { |
|
|
|
window.ws.send(JSON.stringify({ |
|
type: 'request_scene_characters', |
|
scene: this.currentScene |
|
})); |
|
} |
|
} |
|
|
|
clearSelection() { |
|
this.currentScene = null; |
|
const buttons = this.container.querySelectorAll('.scene-btn'); |
|
buttons.forEach(btn => btn.classList.remove('active')); |
|
|
|
|
|
const sceneEvent = new CustomEvent('scene-selected', { |
|
detail: { scene: null } |
|
}); |
|
window.dispatchEvent(sceneEvent); |
|
|
|
if (window.ws && window.ws.readyState === WebSocket.OPEN) { |
|
|
|
window.ws.send(JSON.stringify({ |
|
type: 'request_scene_characters', |
|
scene: null |
|
})); |
|
} |
|
} |
|
} |
|
const scenesPanel = new ScenesPanel(); |