Feature: config UI split across Schedule and Venue panels
This commit is contained in:
parent
03474298a9
commit
066fcc26cc
@ -9,12 +9,14 @@ export class ConfigUI extends SceneFeature {
|
|||||||
super();
|
super();
|
||||||
sceneFeatureManager.register(this);
|
sceneFeatureManager.register(this);
|
||||||
this.toggles = {};
|
this.toggles = {};
|
||||||
|
this.containers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
const container = document.createElement('div');
|
// --- Left Panel: Party Schedule ---
|
||||||
container.id = 'config-ui';
|
const leftContainer = document.createElement('div');
|
||||||
Object.assign(container.style, {
|
leftContainer.id = 'config-ui-left';
|
||||||
|
Object.assign(leftContainer.style, {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: '70px',
|
top: '70px',
|
||||||
left: '20px',
|
left: '20px',
|
||||||
@ -29,6 +31,47 @@ export class ConfigUI extends SceneFeature {
|
|||||||
gap: '10px',
|
gap: '10px',
|
||||||
minWidth: '200px'
|
minWidth: '200px'
|
||||||
});
|
});
|
||||||
|
this.containers.push(leftContainer);
|
||||||
|
|
||||||
|
const heading = document.createElement('h3');
|
||||||
|
heading.innerText = 'Party schedule';
|
||||||
|
Object.assign(heading.style, {
|
||||||
|
margin: '0 0 15px 0',
|
||||||
|
textAlign: 'center',
|
||||||
|
borderBottom: '1px solid #555',
|
||||||
|
paddingBottom: '10px'
|
||||||
|
});
|
||||||
|
leftContainer.appendChild(heading);
|
||||||
|
|
||||||
|
// --- Right Panel: Party Venue ---
|
||||||
|
const rightContainer = document.createElement('div');
|
||||||
|
rightContainer.id = 'config-ui-right';
|
||||||
|
Object.assign(rightContainer.style, {
|
||||||
|
position: 'absolute',
|
||||||
|
top: '70px',
|
||||||
|
right: '20px',
|
||||||
|
zIndex: '1000',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
||||||
|
padding: '15px',
|
||||||
|
borderRadius: '8px',
|
||||||
|
color: 'white',
|
||||||
|
fontFamily: 'sans-serif',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '10px',
|
||||||
|
minWidth: '200px'
|
||||||
|
});
|
||||||
|
this.containers.push(rightContainer);
|
||||||
|
|
||||||
|
const venueHeading = document.createElement('h3');
|
||||||
|
venueHeading.innerText = 'Party venue';
|
||||||
|
Object.assign(venueHeading.style, {
|
||||||
|
margin: '0 0 15px 0',
|
||||||
|
textAlign: 'center',
|
||||||
|
borderBottom: '1px solid #555',
|
||||||
|
paddingBottom: '10px'
|
||||||
|
});
|
||||||
|
rightContainer.appendChild(venueHeading);
|
||||||
|
|
||||||
const saveConfig = () => {
|
const saveConfig = () => {
|
||||||
localStorage.setItem('partyConfig', JSON.stringify(state.config));
|
localStorage.setItem('partyConfig', JSON.stringify(state.config));
|
||||||
@ -56,7 +99,7 @@ export class ConfigUI extends SceneFeature {
|
|||||||
this.toggles[configKey] = { checkbox: chk, callback: onChange };
|
this.toggles[configKey] = { checkbox: chk, callback: onChange };
|
||||||
row.appendChild(lbl);
|
row.appendChild(lbl);
|
||||||
row.appendChild(chk);
|
row.appendChild(chk);
|
||||||
container.appendChild(row);
|
rightContainer.appendChild(row);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Torches Toggle
|
// Torches Toggle
|
||||||
@ -99,14 +142,11 @@ export class ConfigUI extends SceneFeature {
|
|||||||
|
|
||||||
hatRow.appendChild(hatLabel);
|
hatRow.appendChild(hatLabel);
|
||||||
hatRow.appendChild(hatSelect);
|
hatRow.appendChild(hatSelect);
|
||||||
container.appendChild(hatRow);
|
rightContainer.appendChild(hatRow);
|
||||||
|
|
||||||
// --- Status & Control Section ---
|
// --- Status & Control Section ---
|
||||||
const statusContainer = document.createElement('div');
|
const statusContainer = document.createElement('div');
|
||||||
Object.assign(statusContainer.style, {
|
Object.assign(statusContainer.style, {
|
||||||
marginTop: '15px',
|
|
||||||
paddingTop: '10px',
|
|
||||||
borderTop: '1px solid #555',
|
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
gap: '8px'
|
gap: '8px'
|
||||||
@ -143,7 +183,7 @@ export class ConfigUI extends SceneFeature {
|
|||||||
marginTop: '10px',
|
marginTop: '10px',
|
||||||
padding: '8px',
|
padding: '8px',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
backgroundColor: '#555',
|
backgroundColor: '#ff9800', // Default orange
|
||||||
color: 'white',
|
color: 'white',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
borderRadius: '4px',
|
borderRadius: '4px',
|
||||||
@ -168,6 +208,7 @@ export class ConfigUI extends SceneFeature {
|
|||||||
loadPosterBtn.onclick = () => {
|
loadPosterBtn.onclick = () => {
|
||||||
posterInput.click();
|
posterInput.click();
|
||||||
};
|
};
|
||||||
|
this.loadPosterBtn = loadPosterBtn;
|
||||||
statusContainer.appendChild(loadPosterBtn);
|
statusContainer.appendChild(loadPosterBtn);
|
||||||
|
|
||||||
// Load Tapes Button
|
// Load Tapes Button
|
||||||
@ -178,7 +219,7 @@ export class ConfigUI extends SceneFeature {
|
|||||||
marginTop: '10px',
|
marginTop: '10px',
|
||||||
padding: '8px',
|
padding: '8px',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
backgroundColor: '#555',
|
backgroundColor: '#ff9800', // Default orange
|
||||||
color: 'white',
|
color: 'white',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
borderRadius: '4px',
|
borderRadius: '4px',
|
||||||
@ -194,7 +235,7 @@ export class ConfigUI extends SceneFeature {
|
|||||||
marginTop: '10px',
|
marginTop: '10px',
|
||||||
padding: '8px',
|
padding: '8px',
|
||||||
cursor: 'pointer',
|
cursor: 'pointer',
|
||||||
backgroundColor: '#555',
|
backgroundColor: '#ff9800', // Default orange
|
||||||
color: 'white',
|
color: 'white',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
borderRadius: '4px',
|
borderRadius: '4px',
|
||||||
@ -204,6 +245,7 @@ export class ConfigUI extends SceneFeature {
|
|||||||
const fileInput = document.getElementById('musicFileInput');
|
const fileInput = document.getElementById('musicFileInput');
|
||||||
if (fileInput) fileInput.click();
|
if (fileInput) fileInput.click();
|
||||||
};
|
};
|
||||||
|
this.chooseSongBtn = chooseSongBtn;
|
||||||
statusContainer.appendChild(chooseSongBtn);
|
statusContainer.appendChild(chooseSongBtn);
|
||||||
|
|
||||||
// Start Party Button
|
// Start Party Button
|
||||||
@ -214,8 +256,8 @@ export class ConfigUI extends SceneFeature {
|
|||||||
marginTop: '10px',
|
marginTop: '10px',
|
||||||
padding: '10px',
|
padding: '10px',
|
||||||
cursor: 'not-allowed',
|
cursor: 'not-allowed',
|
||||||
backgroundColor: '#333',
|
backgroundColor: '#dc3545', // Default red
|
||||||
color: '#777',
|
color: 'white',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
borderRadius: '4px',
|
borderRadius: '4px',
|
||||||
fontSize: '16px',
|
fontSize: '16px',
|
||||||
@ -227,7 +269,7 @@ export class ConfigUI extends SceneFeature {
|
|||||||
if (musicPlayer) musicPlayer.startSequence();
|
if (musicPlayer) musicPlayer.startSequence();
|
||||||
};
|
};
|
||||||
statusContainer.appendChild(this.startButton);
|
statusContainer.appendChild(this.startButton);
|
||||||
container.appendChild(statusContainer);
|
leftContainer.appendChild(statusContainer);
|
||||||
|
|
||||||
// Reset Button
|
// Reset Button
|
||||||
const resetBtn = document.createElement('button');
|
const resetBtn = document.createElement('button');
|
||||||
@ -293,10 +335,10 @@ export class ConfigUI extends SceneFeature {
|
|||||||
if (this.hatSelect) this.hatSelect.value = defaults.djHat;
|
if (this.hatSelect) this.hatSelect.value = defaults.djHat;
|
||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
};
|
};
|
||||||
container.appendChild(resetBtn);
|
leftContainer.appendChild(resetBtn);
|
||||||
|
|
||||||
document.body.appendChild(container);
|
document.body.appendChild(leftContainer);
|
||||||
this.container = container;
|
document.body.appendChild(rightContainer);
|
||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
|
|
||||||
// Restore poster
|
// Restore poster
|
||||||
@ -311,23 +353,40 @@ export class ConfigUI extends SceneFeature {
|
|||||||
updateStatus() {
|
updateStatus() {
|
||||||
if (!this.songLabel) return;
|
if (!this.songLabel) return;
|
||||||
|
|
||||||
|
const orange = '#ff9800';
|
||||||
|
const green = '#28a745';
|
||||||
|
const red = '#dc3545';
|
||||||
|
|
||||||
// Update Song Info
|
// Update Song Info
|
||||||
if (state.music && state.music.songTitle) {
|
if (state.music && state.music.songTitle) {
|
||||||
this.songLabel.innerText = `Song: ${state.music.songTitle}`;
|
this.songLabel.innerText = `Song: ${state.music.songTitle}`;
|
||||||
this.songLabel.style.color = '#fff';
|
this.songLabel.style.color = '#fff';
|
||||||
|
|
||||||
this.startButton.disabled = false;
|
this.startButton.disabled = false;
|
||||||
this.startButton.style.backgroundColor = '#28a745';
|
this.startButton.style.backgroundColor = green;
|
||||||
this.startButton.style.color = 'white';
|
this.startButton.style.color = 'white';
|
||||||
this.startButton.style.cursor = 'pointer';
|
this.startButton.style.cursor = 'pointer';
|
||||||
|
this.startButton.style.opacity = '1';
|
||||||
|
|
||||||
|
if (this.chooseSongBtn) this.chooseSongBtn.style.backgroundColor = green;
|
||||||
} else {
|
} else {
|
||||||
this.songLabel.innerText = 'Song: (None)';
|
this.songLabel.innerText = 'Song: (None)';
|
||||||
this.songLabel.style.color = '#aaa';
|
this.songLabel.style.color = '#aaa';
|
||||||
|
|
||||||
this.startButton.disabled = true;
|
this.startButton.disabled = true;
|
||||||
this.startButton.style.backgroundColor = '#333';
|
this.startButton.style.backgroundColor = red;
|
||||||
this.startButton.style.color = '#777';
|
this.startButton.style.color = 'white';
|
||||||
|
this.startButton.style.opacity = '0.6';
|
||||||
this.startButton.style.cursor = 'not-allowed';
|
this.startButton.style.cursor = 'not-allowed';
|
||||||
|
|
||||||
|
if (this.chooseSongBtn) this.chooseSongBtn.style.backgroundColor = orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.loadPosterBtn) {
|
||||||
|
this.loadPosterBtn.style.backgroundColor = state.posterImage ? green : orange;
|
||||||
|
}
|
||||||
|
if (state.loadTapeButton) {
|
||||||
|
state.loadTapeButton.style.backgroundColor = (state.videoUrls && state.videoUrls.length > 0) ? green : orange;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Tape List
|
// Update Tape List
|
||||||
@ -356,10 +415,10 @@ export class ConfigUI extends SceneFeature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onPartyStart() {
|
onPartyStart() {
|
||||||
if (this.container) this.container.style.display = 'none';
|
this.containers.forEach(c => c.style.display = 'none');
|
||||||
}
|
}
|
||||||
|
|
||||||
onPartyEnd() {
|
onPartyEnd() {
|
||||||
if (this.container) this.container.style.display = 'flex';
|
this.containers.forEach(c => c.style.display = 'flex');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,10 +77,12 @@ export class MusicPlayer extends SceneFeature {
|
|||||||
|
|
||||||
startSequence() {
|
startSequence() {
|
||||||
const uiContainer = document.getElementById('ui-container');
|
const uiContainer = document.getElementById('ui-container');
|
||||||
const configUI = document.getElementById('config-ui');
|
const configUILeft = document.getElementById('config-ui-left');
|
||||||
|
const configUIRight = document.getElementById('config-ui-right');
|
||||||
|
|
||||||
if (uiContainer) uiContainer.style.display = 'none';
|
if (uiContainer) uiContainer.style.display = 'none';
|
||||||
if (configUI) configUI.style.display = 'none';
|
if (configUILeft) configUILeft.style.display = 'none';
|
||||||
|
if (configUIRight) configUIRight.style.display = 'none';
|
||||||
if (state.loadTapeButton) state.loadTapeButton.classList.add('hidden');
|
if (state.loadTapeButton) state.loadTapeButton.classList.add('hidden');
|
||||||
|
|
||||||
showStandbyScreen();
|
showStandbyScreen();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user