mirror of
https://github.com/easydiffusion/easydiffusion.git
synced 2025-01-13 17:58:26 +01:00
Merge pull request #687 from cmdr2/beta
Undo/redo buttons in the image editor, Drag handle to reorder tasks, Pause button to pause all the tasks
This commit is contained in:
commit
9d201f82f1
@ -27,6 +27,7 @@
|
||||
- Support loading models in the safetensor format, for improved safety
|
||||
|
||||
### Detailed changelog
|
||||
* 2.4.19 - 17 Dec 2022 - Add Undo/Redo buttons in the Image Editor. Thanks @JeLuf
|
||||
* 2.4.19 - 10 Dec 2022 - Show init img in task list
|
||||
* 2.4.19 - 7 Dec 2022 - Use pre-trained hypernetworks while generating images. Thanks @C0bra5
|
||||
* 2.4.19 - 6 Dec 2022 - Allow processing new tasks first. Thanks @madrang
|
||||
|
@ -25,7 +25,7 @@
|
||||
<div id="logo">
|
||||
<h1>
|
||||
Stable Diffusion UI
|
||||
<small>v2.4.19 <span id="updateBranchLabel"></span></small>
|
||||
<small>v2.4.20 <span id="updateBranchLabel"></span></small>
|
||||
</h1>
|
||||
</div>
|
||||
<div id="server-status">
|
||||
@ -100,7 +100,11 @@
|
||||
</div>
|
||||
|
||||
<button id="makeImage" class="primaryButton">Make Image</button>
|
||||
<button id="stopImage" class="secondaryButton">Stop All</button>
|
||||
<div id="render-buttons">
|
||||
<button id="stopImage" class="secondaryButton">Stop All</button>
|
||||
<button id="pause"><i class="fa-solid fa-pause"></i> Pause All</button>
|
||||
<button id="resume"><i class="fa-solid fa-play"></i> Resume</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span class="line-separator"></span>
|
||||
|
@ -136,6 +136,10 @@
|
||||
background: var(--background-color3);
|
||||
}
|
||||
|
||||
.editor-controls-right .image-editor-button {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
#init_image_button_inpaint .input-toggle {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
@ -208,4 +212,4 @@
|
||||
}
|
||||
.image-editor-popup h4 {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
@ -191,15 +191,29 @@ code {
|
||||
background: rgb(132, 8, 0);
|
||||
border: 2px solid rgb(122, 29, 0);
|
||||
color: rgb(255, 221, 255);
|
||||
width: 100%;
|
||||
height: 30pt;
|
||||
border-radius: 6px;
|
||||
display: none;
|
||||
margin-top: 2pt;
|
||||
flex-grow: 2;
|
||||
}
|
||||
#stopImage:hover {
|
||||
background: rgb(177, 27, 0);
|
||||
}
|
||||
|
||||
div#render-buttons {
|
||||
gap: 3px;
|
||||
margin-top: 4px;
|
||||
display: none;
|
||||
}
|
||||
button#pause {
|
||||
flex-grow: 1;
|
||||
background: var(--accent-color);
|
||||
}
|
||||
button#resume {
|
||||
flex-grow: 1;
|
||||
background: var(--accent-color);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
@ -265,7 +279,7 @@ img {
|
||||
}
|
||||
.preview-prompt {
|
||||
font-size: 13pt;
|
||||
margin-bottom: 10pt;
|
||||
display: inline;
|
||||
}
|
||||
#coffeeButton {
|
||||
height: 23px;
|
||||
@ -391,14 +405,34 @@ img {
|
||||
.imageTaskContainer > div > .collapsible-handle {
|
||||
display: none;
|
||||
}
|
||||
.dropTargetBefore::before{
|
||||
content: "";
|
||||
border: 1px solid #fff;
|
||||
margin-bottom: -2px;
|
||||
display: block;
|
||||
box-shadow: 0 0 5px #fff;
|
||||
transform: translate(0px, -14px);
|
||||
}
|
||||
.dropTargetAfter::after{
|
||||
content: "";
|
||||
border: 1px solid #fff;
|
||||
margin-bottom: -2px;
|
||||
display: block;
|
||||
box-shadow: 0 0 5px #fff;
|
||||
transform: translate(0px, 14px);
|
||||
}
|
||||
.drag-handle {
|
||||
margin-right: 6px;
|
||||
cursor: move;
|
||||
}
|
||||
.taskStatusLabel {
|
||||
float: left;
|
||||
font-size: 8pt;
|
||||
background:var(--background-color2);
|
||||
border: 1px solid rgb(61, 62, 66);
|
||||
padding: 2pt 4pt;
|
||||
border-radius: 2pt;
|
||||
margin-right: 5pt;
|
||||
display: inline;
|
||||
}
|
||||
.activeTaskLabel {
|
||||
background:rgb(0, 90, 30);
|
||||
@ -448,6 +482,7 @@ img {
|
||||
font-size: 10pt;
|
||||
color: #aaa;
|
||||
margin-bottom: 5pt;
|
||||
margin-top: 5pt;
|
||||
}
|
||||
.img-batch {
|
||||
display: inline;
|
||||
@ -1068,7 +1103,19 @@ div.task-initimg > img {
|
||||
}
|
||||
div.task-fs-initimage {
|
||||
display: none;
|
||||
# position: absolute;
|
||||
}
|
||||
div.task-initimg:hover div.task-fs-initimage {
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
box-shadow: 0 0 30px #000;
|
||||
margin-top:-64px;
|
||||
}
|
||||
div.top-right {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
}
|
||||
|
||||
button#save-system-settings-btn {
|
||||
@ -1080,3 +1127,50 @@ button#save-system-settings-btn {
|
||||
#ip-info div {
|
||||
line-height: 200%;
|
||||
}
|
||||
|
||||
/* SCROLLBARS */
|
||||
:root {
|
||||
--scrollbar-width: 14px;
|
||||
--scrollbar-radius: 10px;
|
||||
}
|
||||
|
||||
.scrollbar-editor::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.scrollbar-editor::-webkit-scrollbar-track {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.scrollbar-editor::-webkit-scrollbar-thumb {
|
||||
background: --background-color2;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: var(--scrollbar-width);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
box-shadow: inset 0 0 5px var(--input-border-color);
|
||||
border-radius: var(--input-border-radius);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--background-color2);
|
||||
border-radius: var(--scrollbar-radius);
|
||||
}
|
||||
|
||||
body.pause {
|
||||
border: solid 12px var(--accent-color);
|
||||
}
|
||||
|
||||
body.wait-pause {
|
||||
animation: blinker 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes blinker {
|
||||
0% { border: solid 12px var(--accent-color); }
|
||||
50% { border: solid 12px var(--background-color1); }
|
||||
100% { border: solid 12px var(--accent-color); }
|
||||
}
|
||||
|
@ -10,8 +10,8 @@
|
||||
const IDLE_COOLDOWN = 2500 // ms
|
||||
const CONCURRENT_TASK_INTERVAL = 500 // ms
|
||||
|
||||
/** Connects to an endpoint and resumes connexion after reaching end of stream until all data is received.
|
||||
* Allows closing the connexion while the server buffers more data.
|
||||
/** Connects to an endpoint and resumes connection after reaching end of stream until all data is received.
|
||||
* Allows closing the connection while the server buffers more data.
|
||||
*/
|
||||
class ChunkedStreamReader {
|
||||
#bufferedString = '' // Data received waiting to be read.
|
||||
@ -264,11 +264,11 @@
|
||||
|
||||
function isServerAvailable() {
|
||||
if (typeof serverState !== 'object') {
|
||||
console.error('serverState not set to a value. Connexion to server could be lost...')
|
||||
console.error('serverState not set to a value. Connection to server could be lost...')
|
||||
return false
|
||||
}
|
||||
if (Date.now() >= serverState.time + SERVER_STATE_VALIDITY_DURATION) {
|
||||
console.warn('SERVER_STATE_VALIDITY_DURATION elapsed. Connexion to server could be lost...')
|
||||
console.warn('SERVER_STATE_VALIDITY_DURATION elapsed. Connection to server could be lost...')
|
||||
return false
|
||||
}
|
||||
switch (serverState.status) {
|
||||
@ -306,7 +306,7 @@
|
||||
if (await healthCheck() && isServerAvailable()) { // Force a recheck of server status before failure...
|
||||
continue // Continue waiting if last healthCheck confirmed the server is still alive.
|
||||
}
|
||||
throw new Error('Connexion with server lost.')
|
||||
throw new Error('Connection with server lost.')
|
||||
}
|
||||
}
|
||||
if (Date.now() >= serverState.time + SERVER_STATE_VALIDITY_DURATION) {
|
||||
|
@ -105,7 +105,26 @@ const IMAGE_EDITOR_ACTIONS = [
|
||||
icon: "fa-solid fa-xmark",
|
||||
handler: (editor) => {
|
||||
editor.ctx_current.clearRect(0, 0, editor.width, editor.height)
|
||||
}
|
||||
},
|
||||
trackHistory: true
|
||||
},
|
||||
{
|
||||
id: "undo",
|
||||
name: "Undo",
|
||||
icon: "fa-solid fa-rotate-left",
|
||||
handler: (editor) => {
|
||||
editor.history.undo()
|
||||
},
|
||||
trackHistory: false
|
||||
},
|
||||
{
|
||||
id: "redo",
|
||||
name: "Redo",
|
||||
icon: "fa-solid fa-rotate-right",
|
||||
handler: (editor) => {
|
||||
editor.history.redo()
|
||||
},
|
||||
trackHistory: false
|
||||
}
|
||||
]
|
||||
|
||||
@ -436,13 +455,14 @@ class ImageEditor {
|
||||
return
|
||||
}
|
||||
|
||||
var max_size = Math.min(parseInt(window.innerWidth * 0.9), width, 768)
|
||||
if (width > height) {
|
||||
var max_size = Math.min(parseInt(window.innerWidth * 0.9), width, 768)
|
||||
var multiplier = max_size / width
|
||||
width = (multiplier * width).toFixed()
|
||||
height = (multiplier * height).toFixed()
|
||||
}
|
||||
else {
|
||||
var max_size = Math.min(parseInt(window.innerHeight * 0.9), height, 768)
|
||||
var multiplier = max_size / height
|
||||
width = (multiplier * width).toFixed()
|
||||
height = (multiplier * height).toFixed()
|
||||
@ -525,7 +545,9 @@ class ImageEditor {
|
||||
}
|
||||
runAction(action_id) {
|
||||
var action = IMAGE_EDITOR_ACTIONS.find(a => a.id == action_id)
|
||||
this.history.pushAction(action_id)
|
||||
if (action.trackHistory) {
|
||||
this.history.pushAction(action_id)
|
||||
}
|
||||
action.handler(this)
|
||||
}
|
||||
setBrush(layer = null, options = null) {
|
||||
|
@ -45,6 +45,9 @@ let streamImageProgressField = document.querySelector("#stream_image_progress")
|
||||
|
||||
let makeImageBtn = document.querySelector('#makeImage')
|
||||
let stopImageBtn = document.querySelector('#stopImage')
|
||||
let pauseBtn = document.querySelector('#pause')
|
||||
let resumeBtn = document.querySelector('#resume')
|
||||
let renderButtons = document.querySelector('#render-buttons')
|
||||
|
||||
let imagesContainer = document.querySelector('#current-images')
|
||||
let initImagePreviewContainer = document.querySelector('#init_image_preview_container')
|
||||
@ -101,6 +104,8 @@ imagePreview.addEventListener('drop', function(ev) {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
let showConfigToggle = document.querySelector('#configToggleBtn')
|
||||
// let configBox = document.querySelector('#config')
|
||||
// let outputMsg = document.querySelector('#outputMsg')
|
||||
@ -456,6 +461,10 @@ function makeImage() {
|
||||
|
||||
async function onIdle() {
|
||||
const serverCapacity = SD.serverCapacity
|
||||
if (pauseClient===true) {
|
||||
await resumeClient()
|
||||
}
|
||||
|
||||
for (const taskEntry of getUncompletedTaskEntries()) {
|
||||
if (SD.activeTasks.size >= serverCapacity) {
|
||||
break
|
||||
@ -623,19 +632,18 @@ function onTaskCompleted(task, reqBody, instance, outputContainer, stepUpdate) {
|
||||
task['stopTask'].innerHTML = '<i class="fa-solid fa-trash-can"></i> Remove'
|
||||
task['taskStatusLabel'].style.display = 'none'
|
||||
|
||||
let time = Date.now() - task.startTime
|
||||
time /= 1000
|
||||
let time = millisecondsToStr( Date.now() - task.startTime )
|
||||
|
||||
if (task.batchesDone == task.batchCount) {
|
||||
if (!task.outputMsg.innerText.toLowerCase().includes('error')) {
|
||||
task.outputMsg.innerText = `Processed ${task.numOutputsTotal} images in ${time} seconds`
|
||||
}
|
||||
if (!task.outputMsg.innerText.toLowerCase().includes('error')) {
|
||||
task.outputMsg.innerText = `Processed ${task.numOutputsTotal} images in ${time}`
|
||||
}
|
||||
task.progressBar.style.height = "0px"
|
||||
task.progressBar.style.border = "0px solid var(--background-color3)"
|
||||
task.progressBar.classList.remove("active")
|
||||
setStatus('request', 'done', 'success')
|
||||
} else {
|
||||
task.outputMsg.innerText += `Task ended after ${time} seconds`
|
||||
task.outputMsg.innerText += `Task ended after ${time}`
|
||||
}
|
||||
|
||||
if (randomSeedField.checked) {
|
||||
@ -650,7 +658,7 @@ function onTaskCompleted(task, reqBody, instance, outputContainer, stepUpdate) {
|
||||
return
|
||||
}
|
||||
|
||||
stopImageBtn.style.display = 'none'
|
||||
renderButtons.style.display = 'none'
|
||||
renameMakeImageButton()
|
||||
|
||||
if (isSoundEnabled()) {
|
||||
@ -735,7 +743,7 @@ async function onTaskStart(task) {
|
||||
)
|
||||
|
||||
setStatus('request', 'fetching..')
|
||||
stopImageBtn.style.display = 'block'
|
||||
renderButtons.style.display = 'flex'
|
||||
renameMakeImageButton()
|
||||
previewTools.style.display = 'block'
|
||||
}
|
||||
@ -743,23 +751,33 @@ async function onTaskStart(task) {
|
||||
/* Hover effect for the init image in the task list */
|
||||
function createInitImageHover(taskEntry) {
|
||||
var $tooltip = $( taskEntry.querySelector('.task-fs-initimage') )
|
||||
$( taskEntry.querySelector('div.task-initimg > img') ).on('mouseenter', function() {
|
||||
var img = this,
|
||||
$img = $(img),
|
||||
offset = $img.offset();
|
||||
|
||||
$tooltip
|
||||
.css({
|
||||
'top': offset.top,
|
||||
'left': offset.left,
|
||||
'z-index': 99999,
|
||||
'display': 'block'
|
||||
})
|
||||
.append($img.clone().css({width:"", height:""}));
|
||||
})
|
||||
$tooltip.on('mouseleave', function() {
|
||||
$tooltip.empty().addClass('hidden');
|
||||
var img = document.createElement('img')
|
||||
img.src = taskEntry.querySelector('div.task-initimg > img').src
|
||||
$tooltip.append(img)
|
||||
$tooltip.append(`<div class="top-right"><button>Use as Input</button></div>`)
|
||||
$tooltip.find('button').on('click', (e) => { onUseAsInputClick(null,img) } )
|
||||
}
|
||||
|
||||
let startX, startY;
|
||||
function onTaskEntryDragOver(event) {
|
||||
imagePreview.querySelectorAll(".imageTaskContainer").forEach(itc => {
|
||||
if(itc != event.target.closest(".imageTaskContainer")){
|
||||
itc.classList.remove('dropTargetBefore','dropTargetAfter');
|
||||
}
|
||||
});
|
||||
if(event.target.closest(".imageTaskContainer")){
|
||||
if(startX && startY){
|
||||
if(event.target.closest(".imageTaskContainer").offsetTop > startY){
|
||||
event.target.closest(".imageTaskContainer").classList.add('dropTargetAfter');
|
||||
}else if(event.target.closest(".imageTaskContainer").offsetTop < startY){
|
||||
event.target.closest(".imageTaskContainer").classList.add('dropTargetBefore');
|
||||
}else if (event.target.closest(".imageTaskContainer").offsetLeft > startX){
|
||||
event.target.closest(".imageTaskContainer").classList.add('dropTargetAfter');
|
||||
}else if (event.target.closest(".imageTaskContainer").offsetLeft < startX){
|
||||
event.target.closest(".imageTaskContainer").classList.add('dropTargetBefore');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createTask(task) {
|
||||
@ -795,6 +813,7 @@ function createTask(task) {
|
||||
taskEntry.id = `imageTaskContainer-${Date.now()}`
|
||||
taskEntry.className = 'imageTaskContainer'
|
||||
taskEntry.innerHTML = ` <div class="header-content panel collapsible active">
|
||||
<i class="drag-handle fa-solid fa-grip"></i>
|
||||
<div class="taskStatusLabel">Enqueued</div>
|
||||
<button class="secondaryButton stopTask"><i class="fa-solid fa-trash-can"></i> Remove</button>
|
||||
<button class="secondaryButton useSettings"><i class="fa-solid fa-redo"></i> Use these settings</button>
|
||||
@ -808,6 +827,23 @@ function createTask(task) {
|
||||
</div>`
|
||||
|
||||
createCollapsibles(taskEntry)
|
||||
|
||||
let draghandle = taskEntry.querySelector('.drag-handle')
|
||||
draghandle.addEventListener('mousedown', (e) => { taskEntry.setAttribute('draggable',true)})
|
||||
draghandle.addEventListener('mouseup', (e) => { taskEntry.setAttribute('draggable',false)})
|
||||
taskEntry.addEventListener('dragend', (e) => {
|
||||
taskEntry.setAttribute('draggable',false);
|
||||
imagePreview.querySelectorAll(".imageTaskContainer").forEach(itc => {
|
||||
itc.classList.remove('dropTargetBefore','dropTargetAfter');
|
||||
});
|
||||
imagePreview.removeEventListener("dragover", onTaskEntryDragOver );
|
||||
})
|
||||
taskEntry.addEventListener('dragstart', function(e) {
|
||||
imagePreview.addEventListener("dragover", onTaskEntryDragOver );
|
||||
e.dataTransfer.setData("text/plain", taskEntry.id);
|
||||
startX = e.target.closest(".imageTaskContainer").offsetLeft;
|
||||
startY = e.target.closest(".imageTaskContainer").offsetTop;
|
||||
})
|
||||
|
||||
|
||||
if (task.reqBody.init_image !== undefined) {
|
||||
@ -841,24 +877,13 @@ function createTask(task) {
|
||||
|
||||
task.isProcessing = true
|
||||
taskEntry = imagePreview.insertBefore(taskEntry, previewTools.nextSibling)
|
||||
taskEntry.draggable = true
|
||||
htmlTaskMap.set(taskEntry, task)
|
||||
taskEntry.addEventListener('dragstart', function(ev) {
|
||||
ev.dataTransfer.setData("text/plain", ev.target.id);
|
||||
})
|
||||
|
||||
task.previewPrompt.innerText = task.reqBody.prompt
|
||||
if (task.previewPrompt.innerText.trim() === '') {
|
||||
task.previewPrompt.innerHTML = ' ' // allows the results to be collapsed
|
||||
}
|
||||
|
||||
// Allow prompt text to be selected.
|
||||
task.previewPrompt.addEventListener("mouseover", function() {
|
||||
taskEntry.setAttribute("draggable", "false");
|
||||
});
|
||||
task.previewPrompt.addEventListener("mouseout", function() {
|
||||
taskEntry.setAttribute("draggable", "true");
|
||||
});
|
||||
}
|
||||
|
||||
function getCurrentUserRequest() {
|
||||
@ -929,20 +954,29 @@ function getPrompts(prompts) {
|
||||
if (typeof prompts === 'undefined') {
|
||||
prompts = promptField.value
|
||||
}
|
||||
if (prompts.trim() === '') {
|
||||
if (prompts.trim() === '' && activeTags.length === 0) {
|
||||
return ['']
|
||||
}
|
||||
|
||||
prompts = prompts.split('\n')
|
||||
prompts = prompts.map(prompt => prompt.trim())
|
||||
prompts = prompts.filter(prompt => prompt !== '')
|
||||
|
||||
let promptsToMake = applyPermuteOperator(prompts)
|
||||
promptsToMake = applySetOperator(promptsToMake)
|
||||
let promptsToMake = []
|
||||
if (prompts.trim() !== '') {
|
||||
prompts = prompts.split('\n')
|
||||
prompts = prompts.map(prompt => prompt.trim())
|
||||
prompts = prompts.filter(prompt => prompt !== '')
|
||||
|
||||
promptsToMake = applyPermuteOperator(prompts)
|
||||
promptsToMake = applySetOperator(promptsToMake)
|
||||
}
|
||||
const newTags = activeTags.filter(tag => tag.inactive === undefined || tag.inactive === false)
|
||||
if (newTags.length > 0) {
|
||||
const promptTags = newTags.map(x => x.name).join(", ")
|
||||
promptsToMake = promptsToMake.map((prompt) => `${prompt}, ${promptTags}`)
|
||||
if (promptsToMake.length > 0) {
|
||||
promptsToMake = promptsToMake.map((prompt) => `${prompt}, ${promptTags}`)
|
||||
}
|
||||
else
|
||||
{
|
||||
promptsToMake.push(promptTags)
|
||||
}
|
||||
}
|
||||
|
||||
promptsToMake = applyPermuteOperator(promptsToMake)
|
||||
@ -1380,6 +1414,7 @@ function selectTab(tab_id) {
|
||||
tabInfo.tab.classList.toggle("active")
|
||||
tabInfo.content.classList.toggle("active")
|
||||
}
|
||||
document.dispatchEvent(new CustomEvent('tabClick', { detail: tabInfo }))
|
||||
}
|
||||
function linkTabContents(tab) {
|
||||
var name = tab.id.replace("tab-", "")
|
||||
@ -1393,6 +1428,37 @@ function linkTabContents(tab) {
|
||||
tab.addEventListener("click", event => selectTab(tab.id))
|
||||
}
|
||||
|
||||
let pauseClient = false
|
||||
|
||||
function resumeClient() {
|
||||
if (pauseClient) {
|
||||
document.body.classList.remove('wait-pause')
|
||||
document.body.classList.add('pause')
|
||||
}
|
||||
return new Promise(resolve => {
|
||||
let playbuttonclick = function () {
|
||||
resumeBtn.removeEventListener("click", playbuttonclick);
|
||||
resolve("resolved");
|
||||
}
|
||||
resumeBtn.addEventListener("click", playbuttonclick)
|
||||
})
|
||||
}
|
||||
|
||||
pauseBtn.addEventListener("click", function () {
|
||||
pauseClient = true
|
||||
pauseBtn.style.display="none"
|
||||
resumeBtn.style.display = "inline"
|
||||
document.body.classList.add('wait-pause')
|
||||
})
|
||||
|
||||
resumeBtn.addEventListener("click", function () {
|
||||
pauseClient = false
|
||||
resumeBtn.style.display = "none"
|
||||
pauseBtn.style.display = "inline"
|
||||
document.body.classList.remove('pause')
|
||||
document.body.classList.remove('wait-pause')
|
||||
})
|
||||
|
||||
document.querySelectorAll(".tab").forEach(linkTabContents)
|
||||
|
||||
window.addEventListener("beforeunload", function(e) {
|
||||
|
@ -45,6 +45,7 @@ function toggleCollapsible(element) {
|
||||
handle.innerHTML = '➖' // minus
|
||||
}
|
||||
}
|
||||
document.dispatchEvent(new CustomEvent('collapsibleClick', { detail: collapsibleHeader }))
|
||||
|
||||
if (COLLAPSIBLES_INITIALIZED && COLLAPSIBLE_PANELS.includes(element)) {
|
||||
saveCollapsibles()
|
||||
|
@ -43,22 +43,22 @@
|
||||
</style>
|
||||
`)
|
||||
|
||||
const markedScript = document.createElement('script')
|
||||
markedScript.src = '/media/js/marked.min.js'
|
||||
|
||||
markedScript.onload = async function() {
|
||||
loadScript('/media/js/marked.min.js').then(async function() {
|
||||
let appConfig = await fetch('/get/app_config')
|
||||
if (!appConfig.ok) {
|
||||
console.error('[release-notes] Failed to get app_config.')
|
||||
return
|
||||
}
|
||||
appConfig = await appConfig.json()
|
||||
|
||||
let updateBranch = appConfig.update_branch || 'main'
|
||||
const updateBranch = appConfig.update_branch || 'main'
|
||||
|
||||
let releaseNotes = await fetch(`https://raw.githubusercontent.com/cmdr2/stable-diffusion-ui/${updateBranch}/CHANGES.md`)
|
||||
if (releaseNotes.status != 200) {
|
||||
if (!releaseNotes.ok) {
|
||||
console.error('[release-notes] Failed to get CHANGES.md.')
|
||||
return
|
||||
}
|
||||
releaseNotes = await releaseNotes.text()
|
||||
news.innerHTML = marked.parse(releaseNotes)
|
||||
}
|
||||
|
||||
document.querySelector('body').appendChild(markedScript)
|
||||
})
|
||||
})()
|
@ -822,7 +822,7 @@ def _txt2img(opt_W, opt_H, opt_n_samples, opt_ddim_steps, opt_scale, start_code,
|
||||
move_to_cpu(thread_data.modelCS)
|
||||
|
||||
if thread_data.test_sd2 and sampler_name not in ('plms', 'ddim', 'dpm2'):
|
||||
raise Exception('Only plms and ddim samplers are supported right now, in SD 2.0')
|
||||
raise Exception('Only plms, ddim and dpm2 samplers are supported right now, in SD 2.0')
|
||||
|
||||
|
||||
# samples, _ = sampler.sample(S=opt.steps,
|
||||
|
12
ui/server.py
12
ui/server.py
@ -314,9 +314,15 @@ def getUIPlugins():
|
||||
return plugins
|
||||
|
||||
def getIPConfig():
|
||||
ips = socket.gethostbyname_ex(socket.gethostname())
|
||||
ips[2].append(ips[0])
|
||||
return ips[2]
|
||||
try:
|
||||
ips = socket.gethostbyname_ex(socket.gethostname())
|
||||
ips[2].append(ips[0])
|
||||
return ips[2]
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print(traceback.format_exc())
|
||||
return []
|
||||
|
||||
|
||||
@app.get('/get/{key:path}')
|
||||
def read_web_data(key:str=None):
|
||||
|
Loading…
Reference in New Issue
Block a user