mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 20:49:41 +02:00
feat(ui): improve respawn duration with preset buttons
Replace the simple number input for respawn duration with a preset button group (30m, 1h, 2h, 4h, 8h, ∞, Custom). Move duration to be the first option in the Respawn Controller settings. - Add duration preset buttons with visual highlighting for selection - ∞ (unlimited) is selected by default - Custom option reveals a number input for arbitrary values - Reset to default when modal opens Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+42
-2
@@ -1302,20 +1302,60 @@ class ClaudemanApp {
|
||||
respawnSection.style.display = 'none';
|
||||
}
|
||||
|
||||
// Reset duration presets to default (unlimited)
|
||||
this.selectDurationPreset('');
|
||||
|
||||
document.getElementById('sessionOptionsModal').classList.add('active');
|
||||
|
||||
// Focus the name input
|
||||
setTimeout(() => document.getElementById('sessionNameInput').focus(), 100);
|
||||
}
|
||||
|
||||
// Handle duration preset selection
|
||||
selectDurationPreset(value) {
|
||||
// Remove active from all buttons
|
||||
document.querySelectorAll('.duration-preset-btn').forEach(btn => btn.classList.remove('active'));
|
||||
|
||||
// Find and activate the clicked button
|
||||
const btn = document.querySelector(`.duration-preset-btn[data-minutes="${value}"]`);
|
||||
if (btn) btn.classList.add('active');
|
||||
|
||||
// Show/hide custom input
|
||||
const customInput = document.querySelector('.duration-custom-input');
|
||||
const durationInput = document.getElementById('modalRespawnDuration');
|
||||
|
||||
if (value === 'custom') {
|
||||
customInput.classList.add('visible');
|
||||
durationInput.focus();
|
||||
} else {
|
||||
customInput.classList.remove('visible');
|
||||
durationInput.value = ''; // Clear custom value when using preset
|
||||
}
|
||||
}
|
||||
|
||||
// Get selected duration from preset buttons or custom input
|
||||
getSelectedDuration() {
|
||||
const customInput = document.querySelector('.duration-custom-input');
|
||||
const durationInput = document.getElementById('modalRespawnDuration');
|
||||
|
||||
if (customInput.classList.contains('visible')) {
|
||||
// Custom mode - use input value
|
||||
return durationInput.value ? parseInt(durationInput.value) : null;
|
||||
} else {
|
||||
// Preset mode - get from active button
|
||||
const activeBtn = document.querySelector('.duration-preset-btn.active');
|
||||
const minutes = activeBtn?.dataset.minutes;
|
||||
return minutes ? parseInt(minutes) : null;
|
||||
}
|
||||
}
|
||||
|
||||
// Get respawn config from modal inputs
|
||||
getModalRespawnConfig() {
|
||||
const updatePrompt = document.getElementById('modalRespawnPrompt').value;
|
||||
const sendClear = document.getElementById('modalRespawnSendClear').checked;
|
||||
const sendInit = document.getElementById('modalRespawnSendInit').checked;
|
||||
const kickstartPrompt = document.getElementById('modalRespawnKickstart').value.trim() || undefined;
|
||||
const durationStr = document.getElementById('modalRespawnDuration').value;
|
||||
const durationMinutes = durationStr ? parseInt(durationStr) : null;
|
||||
const durationMinutes = this.getSelectedDuration();
|
||||
|
||||
// Auto-compact settings
|
||||
const autoCompactEnabled = document.getElementById('modalAutoCompactEnabled').checked;
|
||||
|
||||
@@ -209,17 +209,28 @@
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<label>Update Prompt</label>
|
||||
<input type="text" id="modalRespawnPrompt" value="update all the docs and CLAUDE.md" placeholder="Prompt to send when idle">
|
||||
<label>Run Duration</label>
|
||||
<div class="duration-presets">
|
||||
<button type="button" class="duration-preset-btn" data-minutes="30" onclick="app.selectDurationPreset('30')">30m</button>
|
||||
<button type="button" class="duration-preset-btn" data-minutes="60" onclick="app.selectDurationPreset('60')">1h</button>
|
||||
<button type="button" class="duration-preset-btn" data-minutes="120" onclick="app.selectDurationPreset('120')">2h</button>
|
||||
<button type="button" class="duration-preset-btn" data-minutes="240" onclick="app.selectDurationPreset('240')">4h</button>
|
||||
<button type="button" class="duration-preset-btn" data-minutes="480" onclick="app.selectDurationPreset('480')">8h</button>
|
||||
<button type="button" class="duration-preset-btn active" data-minutes="" onclick="app.selectDurationPreset('')">∞</button>
|
||||
<div class="duration-custom">
|
||||
<button type="button" class="duration-preset-btn" data-minutes="custom" onclick="app.selectDurationPreset('custom')">Custom</button>
|
||||
<div class="input-suffix input-suffix-sm duration-custom-input">
|
||||
<input type="number" id="modalRespawnDuration" value="" min="1" placeholder="min">
|
||||
<span>min</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="form-hint">How long to run the respawn loop</span>
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
<label>Run Duration</label>
|
||||
<div class="input-suffix">
|
||||
<input type="number" id="modalRespawnDuration" value="" min="1" placeholder="No limit">
|
||||
<span>min</span>
|
||||
</div>
|
||||
<span class="form-hint">Leave empty for unlimited. Respawn stops after duration.</span>
|
||||
<label>Update Prompt</label>
|
||||
<input type="text" id="modalRespawnPrompt" value="update all the docs and CLAUDE.md" placeholder="Prompt to send when idle">
|
||||
</div>
|
||||
|
||||
<div class="form-row">
|
||||
|
||||
@@ -1351,6 +1351,54 @@ body {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
|
||||
/* Duration preset buttons */
|
||||
.duration-presets {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.35rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.duration-preset-btn {
|
||||
padding: 0.4rem 0.7rem;
|
||||
font-size: 0.75rem;
|
||||
background: var(--bg-input);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
color: var(--text-dim);
|
||||
cursor: pointer;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
|
||||
.duration-preset-btn:hover {
|
||||
border-color: var(--border-light);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.duration-preset-btn.active {
|
||||
background: var(--accent);
|
||||
border-color: var(--accent);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.duration-custom {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.35rem;
|
||||
}
|
||||
|
||||
.duration-custom-input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.duration-custom-input.visible {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.duration-custom-input input {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
/* Respawn actions in modal */
|
||||
.respawn-actions {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user