forked from extern/easydiffusion
Merge branch 'beta' into mdiller_settings
This commit is contained in:
commit
5453925e26
@ -9,7 +9,7 @@
|
|||||||
<link rel="stylesheet" href="/media/css/auto-save.css?v=1">
|
<link rel="stylesheet" href="/media/css/auto-save.css?v=1">
|
||||||
<link rel="stylesheet" href="/media/css/main.css?v=1">
|
<link rel="stylesheet" href="/media/css/main.css?v=1">
|
||||||
<link rel="stylesheet" href="/media/css/auto-save.css?v=1">
|
<link rel="stylesheet" href="/media/css/auto-save.css?v=1">
|
||||||
<link rel="stylesheet" href="/media/css/modifier-thumbnails.css?v=1">
|
<link rel="stylesheet" href="/media/css/modifier-thumbnails.css?v=2">
|
||||||
<link rel="stylesheet" href="/media/css/fontawesome-all.min.css?v=1">
|
<link rel="stylesheet" href="/media/css/fontawesome-all.min.css?v=1">
|
||||||
<link rel="stylesheet" href="/media/css/drawingboard.min.css">
|
<link rel="stylesheet" href="/media/css/drawingboard.min.css">
|
||||||
<script src="/media/js/jquery-3.6.1.min.js"></script>
|
<script src="/media/js/jquery-3.6.1.min.js"></script>
|
||||||
@ -19,7 +19,7 @@
|
|||||||
<div id="container">
|
<div id="container">
|
||||||
<div id="top-nav">
|
<div id="top-nav">
|
||||||
<div id="logo">
|
<div id="logo">
|
||||||
<h1>Stable Diffusion UI <small>v2.3.2 <span id="updateBranchLabel"></span></small></h1>
|
<h1>Stable Diffusion UI <small>v2.3.3 <span id="updateBranchLabel"></span></small></h1>
|
||||||
</div>
|
</div>
|
||||||
<ul id="top-nav-items">
|
<ul id="top-nav-items">
|
||||||
<li class="dropdown">
|
<li class="dropdown">
|
||||||
@ -197,22 +197,23 @@
|
|||||||
</select>
|
</select>
|
||||||
</li>
|
</li>
|
||||||
<li class="pl-5"><input id="show_only_filtered_image" name="show_only_filtered_image" type="checkbox" checked> <label for="show_only_filtered_image">Show only the corrected/upscaled image</label></li>
|
<li class="pl-5"><input id="show_only_filtered_image" name="show_only_filtered_image" type="checkbox" checked> <label for="show_only_filtered_image">Show only the corrected/upscaled image</label></li>
|
||||||
<br/>
|
|
||||||
<li><small>The system-related settings have been moved to the top-right corner.</small></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="editor-modifiers" class="panel-box">
|
<div id="editor-modifiers" class="panel-box">
|
||||||
|
<button id="modifier-settings-btn" title="Add custom modifiers"><i class="fa fa-gear"></i></button>
|
||||||
<h4 class="collapsible">Image Modifiers (art styles, tags etc)</h4>
|
<h4 class="collapsible">Image Modifiers (art styles, tags etc)</h4>
|
||||||
<div id="editor-modifiers-entries" class="collapsible-content">
|
<div id="editor-modifiers-entries" class="collapsible-content">
|
||||||
<label for="preview-image">Image Style:</label>
|
<div id="editor-modifiers-entries-toolbar">
|
||||||
<select id="preview-image" name="preview-image" value="portrait">
|
<label for="preview-image">Image Style:</label>
|
||||||
<option value="portrait" selected="">Face</option>
|
<select id="preview-image" name="preview-image" value="portrait">
|
||||||
<option value="landscape">Landscape</option>
|
<option value="portrait" selected="">Face</option>
|
||||||
</select>
|
<option value="landscape">Landscape</option>
|
||||||
|
</select>
|
||||||
<label for="modifier-card-size-slider">Thumbnail Size:</label>
|
|
||||||
<input id="modifier-card-size-slider" name="modifier-card-size-slider" value="0" type="range" min="-3" max="5">
|
<label for="modifier-card-size-slider">Thumbnail Size:</label>
|
||||||
|
<input id="modifier-card-size-slider" name="modifier-card-size-slider" value="0" type="range" min="-3" max="5">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -237,6 +238,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="modifier-settings-config" style="display:none">
|
||||||
|
<div>
|
||||||
|
<span id="modifier-settings-config-close-btn">X</span>
|
||||||
|
<h1>Modifier Settings</h1>
|
||||||
|
<p>Set your custom modifiers (one per line)</p>
|
||||||
|
<textarea id="custom-modifiers-input" placeholder="Enter your custom modifiers, one-per-line"></textarea>
|
||||||
|
<p><small><b>Tip:</b> You can include special characters like {} () [] and |. You can also put multiple comma-separated phrases in a single line, to make a single modifier that combines all of those.</small></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="line-separator"> </div>
|
<div class="line-separator"> </div>
|
||||||
|
|
||||||
<div id="footer" class="panel-box">
|
<div id="footer" class="panel-box">
|
||||||
@ -252,11 +263,11 @@
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<script src="media/js/plugins.js?v=1"></script>
|
<script src="media/js/plugins.js?v=1"></script>
|
||||||
<script src="media/js/utils.js?v=2"></script>
|
<script src="media/js/utils.js?v=3"></script>
|
||||||
<script src="media/js/inpainting-editor.js?v=1"></script>
|
<script src="media/js/inpainting-editor.js?v=1"></script>
|
||||||
<script src="media/js/image-modifiers.js"></script>
|
<script src="media/js/image-modifiers.js?v=3"></script>
|
||||||
<script src="media/js/auto-save.js?v=1"></script>
|
<script src="media/js/auto-save.js?v=1"></script>
|
||||||
<script src="media/js/main.js?v=2"></script>
|
<script src="media/js/main.js?v=4"></script>
|
||||||
<script src="media/js/themes.js?v=1"></script>
|
<script src="media/js/themes.js?v=1"></script>
|
||||||
<script>
|
<script>
|
||||||
async function init() {
|
async function init() {
|
||||||
|
@ -214,3 +214,36 @@
|
|||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
#modifier-settings-btn {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modifier-settings-config {
|
||||||
|
position: fixed;
|
||||||
|
background: rgba(32, 33, 36, 50%);
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
#modifier-settings-config > div {
|
||||||
|
background: var(--background-color2);
|
||||||
|
max-width: 600px;
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 100px;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 30px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#modifier-settings-config-close-btn {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 10px;
|
||||||
|
transform: translate(50%, -50%) scaleX(130%);
|
||||||
|
}
|
||||||
|
#modifier-settings-config textarea {
|
||||||
|
width: 90%;
|
||||||
|
height: 150px;
|
||||||
|
}
|
@ -1,14 +1,20 @@
|
|||||||
let activeTags = []
|
let activeTags = []
|
||||||
let modifiers = []
|
let modifiers = []
|
||||||
|
let customModifiersGroupElement = undefined
|
||||||
|
|
||||||
let editorModifierEntries = document.querySelector('#editor-modifiers-entries')
|
let editorModifierEntries = document.querySelector('#editor-modifiers-entries')
|
||||||
let editorModifierTagsList = document.querySelector('#editor-inputs-tags-list')
|
let editorModifierTagsList = document.querySelector('#editor-inputs-tags-list')
|
||||||
let editorTagsContainer = document.querySelector('#editor-inputs-tags-container')
|
let editorTagsContainer = document.querySelector('#editor-inputs-tags-container')
|
||||||
let modifierCardSizeSlider = document.querySelector('#modifier-card-size-slider')
|
let modifierCardSizeSlider = document.querySelector('#modifier-card-size-slider')
|
||||||
let previewImageField = document.querySelector('#preview-image')
|
let previewImageField = document.querySelector('#preview-image')
|
||||||
|
let modifierSettingsBtn = document.querySelector('#modifier-settings-btn')
|
||||||
|
let modifierSettingsOverlay = document.querySelector('#modifier-settings-config')
|
||||||
|
let customModifiersTextBox = document.querySelector('#custom-modifiers-input')
|
||||||
|
let customModifierEntriesToolbar = document.querySelector('#editor-modifiers-entries-toolbar')
|
||||||
|
|
||||||
const modifierThumbnailPath = 'media/modifier-thumbnails'
|
const modifierThumbnailPath = 'media/modifier-thumbnails'
|
||||||
const activeCardClass = 'modifier-card-active'
|
const activeCardClass = 'modifier-card-active'
|
||||||
|
const CUSTOM_MODIFIERS_KEY = "customModifiers"
|
||||||
|
|
||||||
function createModifierCard(name, previews) {
|
function createModifierCard(name, previews) {
|
||||||
const modifierCard = document.createElement('div')
|
const modifierCard = document.createElement('div')
|
||||||
@ -56,6 +62,70 @@ function createModifierCard(name, previews) {
|
|||||||
return modifierCard
|
return modifierCard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createModifierGroup(modifierGroup, initiallyExpanded) {
|
||||||
|
const title = modifierGroup.category
|
||||||
|
const modifiers = modifierGroup.modifiers
|
||||||
|
|
||||||
|
const titleEl = document.createElement('h5')
|
||||||
|
titleEl.className = 'collapsible'
|
||||||
|
titleEl.innerText = title
|
||||||
|
|
||||||
|
const modifiersEl = document.createElement('div')
|
||||||
|
modifiersEl.classList.add('collapsible-content', 'editor-modifiers-leaf')
|
||||||
|
|
||||||
|
if (initiallyExpanded === true) {
|
||||||
|
titleEl.className += ' active'
|
||||||
|
modifiersEl.style.display = 'block'
|
||||||
|
}
|
||||||
|
|
||||||
|
modifiers.forEach(modObj => {
|
||||||
|
const modifierName = modObj.modifier
|
||||||
|
const modifierPreviews = modObj?.previews?.map(preview => `${modifierThumbnailPath}/${preview.path}`)
|
||||||
|
|
||||||
|
const modifierCard = createModifierCard(modifierName, modifierPreviews)
|
||||||
|
|
||||||
|
if(typeof modifierCard == 'object') {
|
||||||
|
modifiersEl.appendChild(modifierCard)
|
||||||
|
|
||||||
|
modifierCard.addEventListener('click', () => {
|
||||||
|
if (activeTags.map(x => x.name).includes(modifierName)) {
|
||||||
|
// remove modifier from active array
|
||||||
|
activeTags = activeTags.filter(x => x.name != modifierName)
|
||||||
|
modifierCard.classList.remove(activeCardClass)
|
||||||
|
|
||||||
|
modifierCard.querySelector('.modifier-card-image-overlay').innerText = '+'
|
||||||
|
} else {
|
||||||
|
// add modifier to active array
|
||||||
|
activeTags.push({
|
||||||
|
'name': modifierName,
|
||||||
|
'element': modifierCard.cloneNode(true),
|
||||||
|
'originElement': modifierCard,
|
||||||
|
'previews': modifierPreviews
|
||||||
|
})
|
||||||
|
|
||||||
|
modifierCard.classList.add(activeCardClass)
|
||||||
|
|
||||||
|
modifierCard.querySelector('.modifier-card-image-overlay').innerText = '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshTagsList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let brk = document.createElement('br')
|
||||||
|
brk.style.clear = 'both'
|
||||||
|
modifiersEl.appendChild(brk)
|
||||||
|
|
||||||
|
let e = document.createElement('div')
|
||||||
|
e.appendChild(titleEl)
|
||||||
|
e.appendChild(modifiersEl)
|
||||||
|
|
||||||
|
editorModifierEntries.insertBefore(e, customModifierEntriesToolbar.nextSibling)
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
async function loadModifiers() {
|
async function loadModifiers() {
|
||||||
try {
|
try {
|
||||||
let res = await fetch('/get/modifiers')
|
let res = await fetch('/get/modifiers')
|
||||||
@ -64,66 +134,10 @@ async function loadModifiers() {
|
|||||||
|
|
||||||
modifiers = res; // update global variable
|
modifiers = res; // update global variable
|
||||||
|
|
||||||
|
res.reverse()
|
||||||
|
|
||||||
res.forEach((modifierGroup, idx) => {
|
res.forEach((modifierGroup, idx) => {
|
||||||
const title = modifierGroup.category
|
createModifierGroup(modifierGroup, idx === res.length - 1)
|
||||||
const modifiers = modifierGroup.modifiers
|
|
||||||
|
|
||||||
const titleEl = document.createElement('h5')
|
|
||||||
titleEl.className = 'collapsible'
|
|
||||||
titleEl.innerText = title
|
|
||||||
|
|
||||||
const modifiersEl = document.createElement('div')
|
|
||||||
modifiersEl.classList.add('collapsible-content', 'editor-modifiers-leaf')
|
|
||||||
|
|
||||||
if (idx == 0) {
|
|
||||||
titleEl.className += ' active'
|
|
||||||
modifiersEl.style.display = 'block'
|
|
||||||
}
|
|
||||||
|
|
||||||
modifiers.forEach(modObj => {
|
|
||||||
const modifierName = modObj.modifier
|
|
||||||
const modifierPreviews = modObj?.previews?.map(preview => `${modifierThumbnailPath}/${preview.path}`)
|
|
||||||
|
|
||||||
const modifierCard = createModifierCard(modifierName, modifierPreviews)
|
|
||||||
|
|
||||||
if(typeof modifierCard == 'object') {
|
|
||||||
modifiersEl.appendChild(modifierCard)
|
|
||||||
|
|
||||||
modifierCard.addEventListener('click', () => {
|
|
||||||
if (activeTags.map(x => x.name).includes(modifierName)) {
|
|
||||||
// remove modifier from active array
|
|
||||||
activeTags = activeTags.filter(x => x.name != modifierName)
|
|
||||||
modifierCard.classList.remove(activeCardClass)
|
|
||||||
|
|
||||||
modifierCard.querySelector('.modifier-card-image-overlay').innerText = '+'
|
|
||||||
} else {
|
|
||||||
// add modifier to active array
|
|
||||||
activeTags.push({
|
|
||||||
'name': modifierName,
|
|
||||||
'element': modifierCard.cloneNode(true),
|
|
||||||
'originElement': modifierCard,
|
|
||||||
'previews': modifierPreviews
|
|
||||||
})
|
|
||||||
|
|
||||||
modifierCard.classList.add(activeCardClass)
|
|
||||||
|
|
||||||
modifierCard.querySelector('.modifier-card-image-overlay').innerText = '-'
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshTagsList()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
let brk = document.createElement('br')
|
|
||||||
brk.style.clear = 'both'
|
|
||||||
modifiersEl.appendChild(brk)
|
|
||||||
|
|
||||||
let e = document.createElement('div')
|
|
||||||
e.appendChild(titleEl)
|
|
||||||
e.appendChild(modifiersEl)
|
|
||||||
|
|
||||||
editorModifierEntries.appendChild(e)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
createCollapsibles(editorModifierEntries)
|
createCollapsibles(editorModifierEntries)
|
||||||
@ -131,6 +145,8 @@ async function loadModifiers() {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('error fetching modifiers', e)
|
console.log('error fetching modifiers', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadCustomModifiers()
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshTagsList() {
|
function refreshTagsList() {
|
||||||
@ -228,3 +244,51 @@ function resizeModifierCards(val) {
|
|||||||
|
|
||||||
modifierCardSizeSlider.onchange = () => resizeModifierCards(modifierCardSizeSlider.value)
|
modifierCardSizeSlider.onchange = () => resizeModifierCards(modifierCardSizeSlider.value)
|
||||||
previewImageField.onchange = () => changePreviewImages(previewImageField.value)
|
previewImageField.onchange = () => changePreviewImages(previewImageField.value)
|
||||||
|
|
||||||
|
modifierSettingsBtn.addEventListener('click', function() {
|
||||||
|
modifierSettingsOverlay.style.display = 'block'
|
||||||
|
})
|
||||||
|
document.getElementById("modifier-settings-config-close-btn").addEventListener('click', () => {
|
||||||
|
modifierSettingsOverlay.style.display = 'none'
|
||||||
|
})
|
||||||
|
modifierSettingsOverlay.addEventListener('click', (event) => {
|
||||||
|
if (event.target.id == modifierSettingsOverlay.id) {
|
||||||
|
modifierSettingsOverlay.style.display = 'none'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function saveCustomModifiers() {
|
||||||
|
localStorage.setItem(CUSTOM_MODIFIERS_KEY, customModifiersTextBox.value.trim())
|
||||||
|
|
||||||
|
loadCustomModifiers()
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadCustomModifiers() {
|
||||||
|
let customModifiers = localStorage.getItem(CUSTOM_MODIFIERS_KEY, '')
|
||||||
|
customModifiersTextBox.value = customModifiers
|
||||||
|
|
||||||
|
if (customModifiersGroupElement !== undefined) {
|
||||||
|
customModifiersGroupElement.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customModifiers && customModifiers.trim() !== '') {
|
||||||
|
customModifiers = customModifiers.split('\n')
|
||||||
|
customModifiers = customModifiers.filter(m => m.trim() !== '')
|
||||||
|
customModifiers = customModifiers.map(function(m) {
|
||||||
|
return {
|
||||||
|
"modifier": m
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let customGroup = {
|
||||||
|
'category': 'Custom Modifiers',
|
||||||
|
'modifiers': customModifiers
|
||||||
|
}
|
||||||
|
|
||||||
|
customModifiersGroupElement = createModifierGroup(customGroup, true)
|
||||||
|
|
||||||
|
createCollapsibles(customModifiersGroupElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customModifiersTextBox.addEventListener('change', saveCustomModifiers)
|
||||||
|
@ -176,11 +176,6 @@ function logError(msg, res, outputMsg) {
|
|||||||
console.log('request error', res)
|
console.log('request error', res)
|
||||||
setStatus('request', 'error', 'error')
|
setStatus('request', 'error', 'error')
|
||||||
}
|
}
|
||||||
function asyncDelay(timeout) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
setTimeout(resolve, timeout, true)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
function playSound() {
|
function playSound() {
|
||||||
const audio = new Audio('/media/ding.mp3')
|
const audio = new Audio('/media/ding.mp3')
|
||||||
@ -290,7 +285,7 @@ function showImages(reqBody, res, outputContainer, livePreview) {
|
|||||||
{ text: 'Download', on_click: onDownloadImageClick },
|
{ text: 'Download', on_click: onDownloadImageClick },
|
||||||
{ text: 'Make Similar Images', on_click: onMakeSimilarClick },
|
{ text: 'Make Similar Images', on_click: onMakeSimilarClick },
|
||||||
{ text: 'Draw another 25 steps', on_click: onContinueDrawingClick },
|
{ text: 'Draw another 25 steps', on_click: onContinueDrawingClick },
|
||||||
{ text: 'Upscale (new)', on_click: onUpscaleClick, filter: (req, img) => !req.use_upscale },
|
{ text: 'Upscale', on_click: onUpscaleClick, filter: (req, img) => !req.use_upscale },
|
||||||
{ text: 'Fix Faces', on_click: onFixFacesClick, filter: (req, img) => !req.use_face_correction }
|
{ text: 'Fix Faces', on_click: onFixFacesClick, filter: (req, img) => !req.use_face_correction }
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -345,12 +340,20 @@ function onDownloadImageClick(req, img) {
|
|||||||
imgDownload.click()
|
imgDownload.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMakeSimilarClick(req, img) {
|
function modifyCurrentRequest(req, reqDiff) {
|
||||||
let newTaskRequest = getCurrentUserRequest()
|
const newTaskRequest = getCurrentUserRequest()
|
||||||
|
|
||||||
newTaskRequest.reqBody = Object.assign({}, req, {
|
newTaskRequest.reqBody = Object.assign({}, req, reqDiff, {
|
||||||
|
use_cpu: useCPUField.checked
|
||||||
|
})
|
||||||
|
newTaskRequest.seed = newTaskRequest.reqBody.seed
|
||||||
|
|
||||||
|
return newTaskRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMakeSimilarClick(req, img) {
|
||||||
|
const newTaskRequest = modifyCurrentRequest(req, {
|
||||||
num_outputs: 1,
|
num_outputs: 1,
|
||||||
use_cpu: useCPUField.checked,
|
|
||||||
num_inference_steps: 50,
|
num_inference_steps: 50,
|
||||||
guidance_scale: 7.5,
|
guidance_scale: 7.5,
|
||||||
prompt_strength: 0.7,
|
prompt_strength: 0.7,
|
||||||
@ -360,65 +363,42 @@ function onMakeSimilarClick(req, img) {
|
|||||||
|
|
||||||
newTaskRequest.numOutputsTotal = 5
|
newTaskRequest.numOutputsTotal = 5
|
||||||
newTaskRequest.batchCount = 5
|
newTaskRequest.batchCount = 5
|
||||||
newTaskRequest.seed = newTaskRequest.reqBody.seed
|
|
||||||
|
|
||||||
delete newTaskRequest.reqBody.mask
|
delete newTaskRequest.reqBody.mask
|
||||||
|
|
||||||
createTask(newTaskRequest)
|
createTask(newTaskRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onUpscaleClick(req, img) {
|
function enqueueImageVariationTask(req, img, reqDiff) {
|
||||||
let newTaskRequest = getCurrentUserRequest()
|
|
||||||
const imageSeed = img.getAttribute('data-seed')
|
const imageSeed = img.getAttribute('data-seed')
|
||||||
|
|
||||||
newTaskRequest.reqBody = Object.assign({}, req, {
|
const newTaskRequest = modifyCurrentRequest(req, reqDiff, {
|
||||||
num_outputs: 1,
|
num_outputs: 1, // this can be user-configurable in the future
|
||||||
use_cpu: useCPUField.checked,
|
|
||||||
use_upscale: upscaleModelField.value,
|
|
||||||
seed: imageSeed
|
seed: imageSeed
|
||||||
})
|
})
|
||||||
|
|
||||||
newTaskRequest.numOutputsTotal = 1
|
newTaskRequest.numOutputsTotal = 1 // this can be user-configurable in the future
|
||||||
newTaskRequest.batchCount = 1
|
newTaskRequest.batchCount = 1
|
||||||
newTaskRequest.seed = newTaskRequest.reqBody.seed
|
|
||||||
|
|
||||||
createTask(newTaskRequest)
|
createTask(newTaskRequest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onUpscaleClick(req, img) {
|
||||||
|
enqueueImageVariationTask(req, img, {
|
||||||
|
use_upscale: upscaleModelField.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
function onFixFacesClick(req, img) {
|
function onFixFacesClick(req, img) {
|
||||||
let newTaskRequest = getCurrentUserRequest()
|
enqueueImageVariationTask(req, img, {
|
||||||
const imageSeed = img.getAttribute('data-seed')
|
use_face_correction: 'GFPGANv1.3'
|
||||||
|
|
||||||
newTaskRequest.reqBody = Object.assign({}, req, {
|
|
||||||
num_outputs: 1,
|
|
||||||
use_cpu: useCPUField.checked,
|
|
||||||
use_face_correction: 'GFPGANv1.3',
|
|
||||||
seed: imageSeed
|
|
||||||
})
|
})
|
||||||
|
|
||||||
newTaskRequest.numOutputsTotal = 1
|
|
||||||
newTaskRequest.batchCount = 1
|
|
||||||
newTaskRequest.seed = newTaskRequest.reqBody.seed
|
|
||||||
|
|
||||||
createTask(newTaskRequest)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onContinueDrawingClick(req, img) {
|
function onContinueDrawingClick(req, img) {
|
||||||
let newTaskRequest = getCurrentUserRequest()
|
enqueueImageVariationTask(req, img, {
|
||||||
const imageSeed = img.getAttribute('data-seed')
|
num_inference_steps: parseInt(req.num_inference_steps) + 25
|
||||||
|
|
||||||
newTaskRequest.reqBody = Object.assign({}, req, {
|
|
||||||
num_outputs: 1,
|
|
||||||
use_cpu: useCPUField.checked,
|
|
||||||
num_inference_steps: parseInt(req.num_inference_steps) + 25,
|
|
||||||
seed: imageSeed
|
|
||||||
})
|
})
|
||||||
|
|
||||||
newTaskRequest.numOutputsTotal = 1
|
|
||||||
newTaskRequest.batchCount = 1
|
|
||||||
newTaskRequest.seed = newTaskRequest.reqBody.seed
|
|
||||||
|
|
||||||
createTask(newTaskRequest)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// makes a single image. don't call this directly, use makeImage() instead
|
// makes a single image. don't call this directly, use makeImage() instead
|
||||||
@ -427,6 +407,11 @@ async function doMakeImage(task) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const RETRY_DELAY_IF_BUFFER_IS_EMPTY = 1000 // ms
|
||||||
|
const RETRY_DELAY_IF_SERVER_IS_BUSY = 30 * 1000 // ms, status_code 503, already a task running
|
||||||
|
const TASK_START_DELAY_ON_SERVER = 1500 // ms
|
||||||
|
const SERVER_STATE_VALIDITY_DURATION = 10 * 1000 // ms
|
||||||
|
|
||||||
const reqBody = task.reqBody
|
const reqBody = task.reqBody
|
||||||
const batchCount = task.batchCount
|
const batchCount = task.batchCount
|
||||||
const outputContainer = document.createElement('div')
|
const outputContainer = document.createElement('div')
|
||||||
@ -452,11 +437,13 @@ async function doMakeImage(task) {
|
|||||||
})
|
})
|
||||||
renderRequest = await res.json()
|
renderRequest = await res.json()
|
||||||
// status_code 503, already a task running.
|
// status_code 503, already a task running.
|
||||||
} while (renderRequest.status_code === 503 && await asyncDelay(30 * 1000))
|
} while (res.status === 503 && await asyncDelay(RETRY_DELAY_IF_SERVER_IS_BUSY))
|
||||||
|
|
||||||
if (typeof renderRequest?.stream !== 'string') {
|
if (typeof renderRequest?.stream !== 'string') {
|
||||||
console.log('Endpoint response: ', renderRequest)
|
console.log('Endpoint response: ', renderRequest)
|
||||||
throw new Error('Endpoint response does not contains a response stream url.')
|
throw new Error('Endpoint response does not contains a response stream url.')
|
||||||
}
|
}
|
||||||
|
|
||||||
task['taskStatusLabel'].innerText = "Waiting"
|
task['taskStatusLabel'].innerText = "Waiting"
|
||||||
task['taskStatusLabel'].classList.add('waitingTaskLabel')
|
task['taskStatusLabel'].classList.add('waitingTaskLabel')
|
||||||
task['taskStatusLabel'].classList.remove('activeTaskLabel')
|
task['taskStatusLabel'].classList.remove('activeTaskLabel')
|
||||||
@ -466,7 +453,8 @@ async function doMakeImage(task) {
|
|||||||
if (!isServerAvailable()) {
|
if (!isServerAvailable()) {
|
||||||
throw new Error('Connexion with server lost.')
|
throw new Error('Connexion with server lost.')
|
||||||
}
|
}
|
||||||
} while (serverState.time > (Date.now() - (10 * 1000)) && serverState.task !== renderRequest.task)
|
} while (Date.now() < (serverState.time + SERVER_STATE_VALIDITY_DURATION) && serverState.task !== renderRequest.task)
|
||||||
|
|
||||||
if (serverState.session !== 'pending' && serverState.session !== 'running' && serverState.session !== 'buffer') {
|
if (serverState.session !== 'pending' && serverState.session !== 'running' && serverState.session !== 'buffer') {
|
||||||
if (serverState.session === 'stopped') {
|
if (serverState.session === 'stopped') {
|
||||||
return false
|
return false
|
||||||
@ -474,9 +462,10 @@ async function doMakeImage(task) {
|
|||||||
|
|
||||||
throw new Error('Unexpected server task state: ' + serverState.session || 'Undefined')
|
throw new Error('Unexpected server task state: ' + serverState.session || 'Undefined')
|
||||||
}
|
}
|
||||||
|
|
||||||
while (serverState.task === renderRequest.task && serverState.session === 'pending') {
|
while (serverState.task === renderRequest.task && serverState.session === 'pending') {
|
||||||
// Wait for task to start on server.
|
// Wait for task to start on server.
|
||||||
await asyncDelay(1500)
|
await asyncDelay(TASK_START_DELAY_ON_SERVER)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Task started!
|
// Task started!
|
||||||
@ -570,7 +559,7 @@ async function doMakeImage(task) {
|
|||||||
}
|
}
|
||||||
if (readComplete && finalJSON.length <= 0) {
|
if (readComplete && finalJSON.length <= 0) {
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
await asyncDelay(1000)
|
await asyncDelay(RETRY_DELAY_IF_BUFFER_IS_EMPTY)
|
||||||
res = await fetch(renderRequest.stream, {
|
res = await fetch(renderRequest.stream, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -641,7 +630,7 @@ async function checkTasks() {
|
|||||||
setStatus('request', 'done', 'success')
|
setStatus('request', 'done', 'success')
|
||||||
setTimeout(checkTasks, 500)
|
setTimeout(checkTasks, 500)
|
||||||
stopImageBtn.style.display = 'none'
|
stopImageBtn.style.display = 'none'
|
||||||
makeImageBtn.innerHTML = 'Make Image'
|
renameMakeImageButton()
|
||||||
|
|
||||||
currentTask = null
|
currentTask = null
|
||||||
|
|
||||||
@ -658,7 +647,7 @@ async function checkTasks() {
|
|||||||
setStatus('request', 'fetching..')
|
setStatus('request', 'fetching..')
|
||||||
|
|
||||||
stopImageBtn.style.display = 'block'
|
stopImageBtn.style.display = 'block'
|
||||||
makeImageBtn.innerHTML = 'Enqueue Next Image'
|
renameMakeImageButton()
|
||||||
bellPending = true
|
bellPending = true
|
||||||
|
|
||||||
previewTools.style.display = 'block'
|
previewTools.style.display = 'block'
|
||||||
@ -1019,6 +1008,21 @@ stopImageBtn.addEventListener('click', async function() {
|
|||||||
widthField.addEventListener('change', onDimensionChange)
|
widthField.addEventListener('change', onDimensionChange)
|
||||||
heightField.addEventListener('change', onDimensionChange)
|
heightField.addEventListener('change', onDimensionChange)
|
||||||
|
|
||||||
|
function renameMakeImageButton() {
|
||||||
|
let totalImages = Math.max(parseInt(numOutputsTotalField.value), parseInt(numOutputsParallelField.value))
|
||||||
|
let imageLabel = 'Image'
|
||||||
|
if (totalImages > 1) {
|
||||||
|
imageLabel = totalImages + ' Images'
|
||||||
|
}
|
||||||
|
if (taskQueue.length == 0) {
|
||||||
|
makeImageBtn.innerText = 'Make ' + imageLabel
|
||||||
|
} else {
|
||||||
|
makeImageBtn.innerText = 'Enqueue Next ' + imageLabel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
numOutputsTotalField.addEventListener('change', renameMakeImageButton)
|
||||||
|
numOutputsParallelField.addEventListener('change', renameMakeImageButton)
|
||||||
|
|
||||||
function onDimensionChange() {
|
function onDimensionChange() {
|
||||||
if (!maskSetting.checked) {
|
if (!maskSetting.checked) {
|
||||||
return
|
return
|
||||||
@ -1053,6 +1057,7 @@ function updateGuidanceScaleSlider() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
guidanceScaleSlider.value = guidanceScaleField.value * 10
|
guidanceScaleSlider.value = guidanceScaleField.value * 10
|
||||||
|
guidanceScaleSlider.dispatchEvent(new Event("change"))
|
||||||
}
|
}
|
||||||
|
|
||||||
guidanceScaleSlider.addEventListener('input', updateGuidanceScale)
|
guidanceScaleSlider.addEventListener('input', updateGuidanceScale)
|
||||||
@ -1072,6 +1077,7 @@ function updatePromptStrengthSlider() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
promptStrengthSlider.value = promptStrengthField.value * 100
|
promptStrengthSlider.value = promptStrengthField.value * 100
|
||||||
|
promptStrengthSlider.dispatchEvent(new Event("change"))
|
||||||
}
|
}
|
||||||
|
|
||||||
promptStrengthSlider.addEventListener('input', updatePromptStrength)
|
promptStrengthSlider.addEventListener('input', updatePromptStrength)
|
||||||
@ -1081,7 +1087,7 @@ updatePromptStrength()
|
|||||||
useBetaChannelField.addEventListener('click', async function(e) {
|
useBetaChannelField.addEventListener('click', async function(e) {
|
||||||
if (!isServerAvailable()) {
|
if (!isServerAvailable()) {
|
||||||
// logError('The server is still starting up..')
|
// logError('The server is still starting up..')
|
||||||
alert('The server is not available.')
|
alert('The server is still starting up..')
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ async function loadUIPlugins() {
|
|||||||
res = await res.json()
|
res = await res.json()
|
||||||
res.forEach(pluginPath => {
|
res.forEach(pluginPath => {
|
||||||
let script = document.createElement('script')
|
let script = document.createElement('script')
|
||||||
script.src = pluginPath
|
script.src = pluginPath + '?t=' + Date.now()
|
||||||
|
|
||||||
console.log('loading plugin', pluginPath)
|
console.log('loading plugin', pluginPath)
|
||||||
|
|
||||||
|
@ -336,3 +336,9 @@ function BraceExpander() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function asyncDelay(timeout) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
setTimeout(resolve, timeout, true)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 21 KiB |
Binary file not shown.
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 21 KiB |
@ -318,7 +318,6 @@ def do_mk_img(req: Request):
|
|||||||
opt_ddim_eta = 0.0
|
opt_ddim_eta = 0.0
|
||||||
opt_init_img = req.init_image
|
opt_init_img = req.init_image
|
||||||
|
|
||||||
|
|
||||||
print(req.to_string(), '\n device', device)
|
print(req.to_string(), '\n device', device)
|
||||||
|
|
||||||
print('\n\n Using precision:', precision)
|
print('\n\n Using precision:', precision)
|
||||||
@ -507,7 +506,7 @@ def do_mk_img(req: Request):
|
|||||||
if (len(filters_applied) > 0):
|
if (len(filters_applied) > 0):
|
||||||
filtered_image = Image.fromarray(x_sample)
|
filtered_image = Image.fromarray(x_sample)
|
||||||
filtered_img_data = img_to_base64_str(filtered_image, req.output_format)
|
filtered_img_data = img_to_base64_str(filtered_image, req.output_format)
|
||||||
response_image = ResponseImage(data=filtered_img_data, seed=req.seed)
|
response_image = ResponseImage(data=filtered_img_data, seed=opt_seed)
|
||||||
res.images.append(response_image)
|
res.images.append(response_image)
|
||||||
if req.save_to_disk_path is not None:
|
if req.save_to_disk_path is not None:
|
||||||
filtered_img_out_path = get_base_path(req.save_to_disk_path, req.session_id, prompts[0], img_id, req.output_format, "_".join(filters_applied))
|
filtered_img_out_path = get_base_path(req.save_to_disk_path, req.session_id, prompts[0], img_id, req.output_format, "_".join(filters_applied))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
TASK_TTL = 15 * 60 # Discard last session's task timeout
|
TASK_TTL = 15 * 60 # seconds, Discard last session's task timeout
|
||||||
|
|
||||||
import queue, threading, time
|
import queue, threading, time
|
||||||
from typing import Any, Generator, Hashable, Optional, Union
|
from typing import Any, Generator, Hashable, Optional, Union
|
||||||
|
Loading…
Reference in New Issue
Block a user