Presets are saved generation recipes that combine all resource types (character, outfit, action, style, scene, detailer, look, checkpoint) with per-field on/off/random toggles. At generation time, entities marked "random" are picked from the DB and fields marked "random" are randomly included or excluded. - Preset model + sync_presets() following existing category pattern - _resolve_preset_entity() / _resolve_preset_fields() helpers - Full route set: index, detail, generate, edit, upload, clone, save_json, create (LLM), rescan - 4 templates: index (gallery), detail (summary + generate), edit (3-way toggle UI), create (LLM form) - example_01.json reference preset + preset_system.txt LLM prompt - Presets nav link in layout.html Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
81 lines
4.1 KiB
HTML
81 lines
4.1 KiB
HTML
{% extends "layout.html" %}
|
|
|
|
{% block content %}
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h1>Create Preset</h1>
|
|
<a href="{{ url_for('presets_index') }}" class="btn btn-outline-secondary">Cancel</a>
|
|
</div>
|
|
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
{% if messages %}
|
|
{% for category, message in messages %}
|
|
<div class="alert alert-{{ 'danger' if category == 'error' else 'success' }} alert-dismissible fade show">{{ message }}<button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>
|
|
{% endfor %}
|
|
{% endif %}
|
|
{% endwith %}
|
|
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-7">
|
|
<div class="card">
|
|
<div class="card-header bg-dark text-white">New Preset</div>
|
|
<div class="card-body">
|
|
<form action="{{ url_for('create_preset') }}" method="post">
|
|
<div class="mb-3">
|
|
<label for="name" class="form-label">Preset Name <span class="text-danger">*</span></label>
|
|
<input type="text" class="form-control" id="name" name="name" required placeholder="e.g. Beach Day Casual">
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="form-check form-switch">
|
|
<input class="form-check-input" type="checkbox" id="use_llm" name="use_llm" checked>
|
|
<label class="form-check-label" for="use_llm">Use AI to build preset from description</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3" id="description-section">
|
|
<label for="description" class="form-label">Description</label>
|
|
<textarea class="form-control" id="description" name="description" rows="5"
|
|
placeholder="Describe the kind of generations you want this preset to produce. Include the type of character, setting, mood, outfit style, etc.
|
|
|
|
Example: A random character in a cheerful beach scene, wearing a swimsuit, with a random action pose. Always include identity and wardrobe fields. Randomise headwear and accessories. No style LoRA needed."></textarea>
|
|
<div class="form-text">The AI will set entity IDs (specific, random, or none) and field toggles (on/off/random) based on your description.</div>
|
|
</div>
|
|
|
|
<div class="d-grid">
|
|
<button type="submit" class="btn btn-success" id="create-btn">Create Preset</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card mt-3">
|
|
<div class="card-header">About Presets</div>
|
|
<div class="card-body text-muted small">
|
|
<p>A <strong>preset</strong> is a saved generation recipe. It stores:</p>
|
|
<ul>
|
|
<li><strong>Entity selections</strong> — which character, action, scene, etc. to use. Set to a specific ID, <span class="badge bg-warning text-dark">Random</span> (pick at generation time), or None.</li>
|
|
<li><strong>Field toggles</strong> — which prompt fields to include. Each can be <span class="badge bg-success">ON</span>, <span class="badge bg-secondary">OFF</span>, or <span class="badge bg-warning text-dark">RNG</span> (randomly decide each generation).</li>
|
|
</ul>
|
|
<p class="mb-0">After creation you'll be taken to the edit page to review and adjust the AI's choices before generating.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
document.getElementById('use_llm').addEventListener('change', function() {
|
|
document.getElementById('description-section').style.display = this.checked ? '' : 'none';
|
|
});
|
|
|
|
document.querySelector('form').addEventListener('submit', function() {
|
|
const btn = document.getElementById('create-btn');
|
|
if (document.getElementById('use_llm').checked) {
|
|
btn.disabled = true;
|
|
btn.textContent = 'Generating with AI...';
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|