feat: improve UI
This commit is contained in:
@@ -16,11 +16,29 @@ class PresetControls extends Component {
|
||||
}
|
||||
|
||||
setupEventListeners() {
|
||||
// Preset selection
|
||||
// FPS slider
|
||||
const fpsSlider = this.findElement('#fps-slider');
|
||||
const fpsValue = this.findElement('#fps-value');
|
||||
if (fpsSlider && fpsValue) {
|
||||
this.addEventListener(fpsSlider, 'input', (e) => {
|
||||
const fps = parseInt(e.target.value);
|
||||
fpsValue.textContent = fps;
|
||||
this.updateFrameRate(fps);
|
||||
});
|
||||
}
|
||||
|
||||
// Preset selection - immediate switching
|
||||
const presetSelect = this.findElement('#preset-select');
|
||||
if (presetSelect) {
|
||||
this.addEventListener(presetSelect, 'change', (e) => {
|
||||
this.selectPreset(e.target.value);
|
||||
const presetName = e.target.value;
|
||||
this.selectPreset(presetName);
|
||||
|
||||
// If currently streaming, automatically restart with new preset
|
||||
const toggleBtn = this.findElement('#toggle-stream-btn');
|
||||
if (toggleBtn && toggleBtn.dataset.streaming === 'true' && presetName) {
|
||||
this.startStreaming();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -32,18 +50,16 @@ class PresetControls extends Component {
|
||||
});
|
||||
}
|
||||
|
||||
// Start/Stop buttons
|
||||
const startBtn = this.findElement('#start-btn');
|
||||
if (startBtn) {
|
||||
this.addEventListener(startBtn, 'click', () => {
|
||||
this.startStreaming();
|
||||
});
|
||||
}
|
||||
|
||||
const stopBtn = this.findElement('#stop-btn');
|
||||
if (stopBtn) {
|
||||
this.addEventListener(stopBtn, 'click', () => {
|
||||
this.stopStreaming();
|
||||
// Toggle stream button
|
||||
const toggleStreamBtn = this.findElement('#toggle-stream-btn');
|
||||
if (toggleStreamBtn) {
|
||||
this.addEventListener(toggleStreamBtn, 'click', () => {
|
||||
const isStreaming = toggleStreamBtn.dataset.streaming === 'true';
|
||||
if (isStreaming) {
|
||||
this.stopStreaming();
|
||||
} else {
|
||||
this.startStreaming();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -73,7 +89,21 @@ class PresetControls extends Component {
|
||||
});
|
||||
|
||||
this.subscribeToEvent('presetParameterUpdated', (data) => {
|
||||
this.updatePresetParameter(data.parameter, data.value);
|
||||
// Update control display without triggering another update
|
||||
const control = this.presetControls.get(data.parameter);
|
||||
if (control) {
|
||||
if (control.type === 'range') {
|
||||
control.value = data.value;
|
||||
const valueDisplay = control.parentElement.querySelector('.preset-value');
|
||||
if (valueDisplay) {
|
||||
valueDisplay.textContent = parseFloat(data.value).toFixed(2);
|
||||
}
|
||||
} else if (control.type === 'color') {
|
||||
control.value = this.hexToColorValue(data.value);
|
||||
} else {
|
||||
control.value = data.value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -82,15 +112,28 @@ class PresetControls extends Component {
|
||||
const isStreaming = data.data.streaming;
|
||||
const currentPreset = data.data.currentPreset;
|
||||
const presetParameters = data.data.presetParameters;
|
||||
const fps = data.data.fps;
|
||||
|
||||
this.updateStreamingState(isStreaming, currentPreset ? { name: currentPreset } : null);
|
||||
|
||||
if (currentPreset) {
|
||||
this.selectPreset(currentPreset.toLowerCase().replace('-preset', ''));
|
||||
// Update FPS display
|
||||
if (fps !== undefined) {
|
||||
const fpsSlider = this.findElement('#fps-slider');
|
||||
const fpsValue = this.findElement('#fps-value');
|
||||
if (fpsSlider && fpsValue) {
|
||||
fpsSlider.value = fps;
|
||||
fpsValue.textContent = fps;
|
||||
}
|
||||
}
|
||||
|
||||
// Only select preset if it's different from current (avoid recreating controls)
|
||||
const presetSelect = this.findElement('#preset-select');
|
||||
if (currentPreset && presetSelect && presetSelect.value !== currentPreset) {
|
||||
this.selectPreset(currentPreset);
|
||||
}
|
||||
|
||||
if (presetParameters && this.currentPreset) {
|
||||
// Update parameter controls with current values
|
||||
// Update parameter controls with current values without triggering events
|
||||
Object.entries(presetParameters).forEach(([param, value]) => {
|
||||
const control = this.presetControls.get(param);
|
||||
if (control) {
|
||||
@@ -109,6 +152,15 @@ class PresetControls extends Component {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.subscribeToEvent('frameRateUpdated', (data) => {
|
||||
const fpsSlider = this.findElement('#fps-slider');
|
||||
const fpsValue = this.findElement('#fps-value');
|
||||
if (fpsSlider && fpsValue && data.fps) {
|
||||
fpsSlider.value = data.fps;
|
||||
fpsValue.textContent = data.fps;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async loadPresets() {
|
||||
@@ -201,8 +253,15 @@ class PresetControls extends Component {
|
||||
valueDisplay.textContent = defaultValue;
|
||||
|
||||
sliderInput.addEventListener('input', (e) => {
|
||||
valueDisplay.textContent = parseFloat(e.target.value).toFixed(2);
|
||||
this.updatePresetParameter(paramName, parseFloat(e.target.value));
|
||||
const value = parseFloat(e.target.value);
|
||||
valueDisplay.textContent = value.toFixed(2);
|
||||
this.updatePresetParameter(paramName, value);
|
||||
|
||||
// Visual feedback for real-time update
|
||||
valueDisplay.style.color = 'var(--accent-primary)';
|
||||
setTimeout(() => {
|
||||
valueDisplay.style.color = '';
|
||||
}, 200);
|
||||
});
|
||||
|
||||
const container = document.createElement('div');
|
||||
@@ -223,6 +282,12 @@ class PresetControls extends Component {
|
||||
colorInput.addEventListener('input', (e) => {
|
||||
const hexValue = this.colorValueToHex(e.target.value);
|
||||
this.updatePresetParameter(paramName, hexValue);
|
||||
|
||||
// Visual feedback for real-time update
|
||||
colorInput.style.borderColor = 'var(--accent-primary)';
|
||||
setTimeout(() => {
|
||||
colorInput.style.borderColor = '';
|
||||
}, 200);
|
||||
});
|
||||
|
||||
return colorInput;
|
||||
@@ -235,6 +300,12 @@ class PresetControls extends Component {
|
||||
|
||||
textInput.addEventListener('input', (e) => {
|
||||
this.updatePresetParameter(paramName, e.target.value);
|
||||
|
||||
// Visual feedback for real-time update
|
||||
textInput.style.borderColor = 'var(--accent-primary)';
|
||||
setTimeout(() => {
|
||||
textInput.style.borderColor = '';
|
||||
}, 200);
|
||||
});
|
||||
|
||||
return textInput;
|
||||
@@ -242,11 +313,13 @@ class PresetControls extends Component {
|
||||
}
|
||||
|
||||
updatePresetParameter(parameter, value) {
|
||||
// Send parameter update to server
|
||||
// Send parameter update to server immediately (real-time)
|
||||
this.viewModel.publish('updatePresetParameter', {
|
||||
parameter,
|
||||
value
|
||||
});
|
||||
|
||||
console.log(`Parameter updated: ${parameter} = ${value}`);
|
||||
}
|
||||
|
||||
clearPresetControls() {
|
||||
@@ -353,17 +426,30 @@ class PresetControls extends Component {
|
||||
}
|
||||
|
||||
updateStreamingState(isStreaming, preset) {
|
||||
const startBtn = this.findElement('#start-btn');
|
||||
const stopBtn = this.findElement('#stop-btn');
|
||||
const toggleBtn = this.findElement('#toggle-stream-btn');
|
||||
const btnIcon = toggleBtn?.querySelector('.btn-icon');
|
||||
const btnText = toggleBtn?.querySelector('.btn-text');
|
||||
|
||||
if (isStreaming) {
|
||||
startBtn.disabled = true;
|
||||
stopBtn.disabled = false;
|
||||
} else {
|
||||
startBtn.disabled = false;
|
||||
stopBtn.disabled = true;
|
||||
if (toggleBtn) {
|
||||
toggleBtn.dataset.streaming = isStreaming ? 'true' : 'false';
|
||||
|
||||
if (isStreaming) {
|
||||
if (btnIcon) btnIcon.textContent = '⏸';
|
||||
if (btnText) btnText.textContent = 'Stop Streaming';
|
||||
toggleBtn.classList.remove('btn-primary');
|
||||
toggleBtn.classList.add('btn-stop');
|
||||
} else {
|
||||
if (btnIcon) btnIcon.textContent = '▶';
|
||||
if (btnText) btnText.textContent = 'Start Streaming';
|
||||
toggleBtn.classList.remove('btn-stop');
|
||||
toggleBtn.classList.add('btn-primary');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateFrameRate(fps) {
|
||||
this.viewModel.publish('updateFrameRate', { fps });
|
||||
}
|
||||
}
|
||||
|
||||
// Export for use in other modules
|
||||
|
||||
Reference in New Issue
Block a user