feat: ✨ add support for subdirs (i/o sidebar)

fixes #221
This commit is contained in:
Mel Massadian
2024-12-22 01:28:08 +01:00
parent d6e004cce2
commit 52bd76e19c
4 changed files with 100 additions and 43 deletions
+19 -1
View File
@@ -66,12 +66,23 @@ def ACTIONS_installDependency(dependency_names: list[str] | None = None):
# break
def ACTIONS_getUserImageFolders():
input_dir = Path(folder_paths.get_input_directory())
output_dir = Path(folder_paths.get_output_directory())
input_subdirs = [x.name for x in input_dir.iterdir() if x.is_dir()]
output_subdirs = [x.name for x in output_dir.iterdir() if x.is_dir()]
return {"input": input_subdirs, "output": output_subdirs}
def ACTIONS_getUserImages(
mode: Literal["input", "output"],
count=1000,
offset=0,
sort: str | None = None,
include_subfolders: bool = False,
subfolder=None,
):
# enabled = "MTB_EXPOSE" in os.environ
# if not enabled:
@@ -84,6 +95,13 @@ def ACTIONS_getUserImages(
output_dir = Path(folder_paths.get_output_directory())
entry_dir = input_dir if mode == "input" else output_dir
if subfolder:
entry_dir = entry_dir / subfolder
if not entry_dir.exists():
return {
"error": f"Subfolder {entry_dir.name} doesn't exists in {entry_dir.parent.as_posix()}"
}
supported = ["png", "jpg", "jpeg", "webp", "gif"]
entries = {}
@@ -105,7 +123,7 @@ def ACTIONS_getUserImages(
imgs = {
img.name: (
f"/mtb/view?filename={img.name}&width=512&type={mode}&subfolder="
f"/mtb/view?filename={img.name}&width=512&type={mode}&subfolder={subfolder or ''}"
f"{img.parent.relative_to(entry_dir) if include_subfolders else ''}"
f"&preview=&rand={secrets.randbelow(424242)}"
)
+29 -3
View File
@@ -1,10 +1,9 @@
/**
* @module Shared utilities
* File: comfy_shared.js
* Project: comfy_mtb
* Author: Mel Massadian
*
* Copyright (c) 2023-2024 Mel Massadian
*
*/
// Reference the shared typedefs file
@@ -1095,7 +1094,33 @@ export const addDeprecation = (nodeType, reason) => {
// #endregion
// #region API / graph utilities
// #region Actions API
export const runAction = async (name, ...args) => {
const req = await api.fetchApi('/mtb/actions', {
method: 'POST',
body: JSON.stringify({
name,
args,
}),
})
const res = await req.json()
return res.result
}
export const getServerInfo = async () => {
const res = await api.fetchApi('/mtb/server-info')
return await res.json()
}
export const setServerInfo = async (opts) => {
await api.fetchApi('/mtb/server-info', {
method: 'POST',
body: JSON.stringify(opts),
})
}
// #endregion
// #region Authoring API / graph utilities
export const getAPIInputs = () => {
const inputs = {}
let counter = 1
@@ -1148,3 +1173,4 @@ export const getNodes = (skip_unused) => {
}
return nodes
}
// #endregion
+42 -19
View File
@@ -1,7 +1,7 @@
import { app } from '../../scripts/app.js'
import { api } from '../../scripts/api.js'
// import * as shared from './comfy_shared.js'
import * as shared from './comfy_shared.js'
import {
// defineCSSClass,
@@ -15,6 +15,8 @@ import {
const offset = 0
let currentWidth = 200
let currentMode = 'input'
let modes = []
let subfolder = ''
let currentSort = 'None'
const IMAGE_NODES = ['LoadImage']
@@ -76,19 +78,23 @@ const getImgsFromUrls = (urls, target) => {
return imgs
}
const getUrls = async () => {
const getModes = async () => {
const inputs = await shared.runAction('getUserImageFolders')
return inputs
}
const getUrls = async (subfolder) => {
const count = (await api.getSetting('mtb.io-sidebar.count')) || 1000
console.log('Sidebar count', count)
const inputs = await api.fetchApi('/mtb/actions', {
method: 'POST',
body: JSON.stringify({
name: 'getUserImages',
// mode, count, offset
args: [currentMode, count, offset, currentSort],
}),
})
const output = await inputs.json()
return output?.result || {}
const output = await shared.runAction(
'getUserImages',
currentMode,
count,
offset,
currentSort,
false,
subfolder,
)
return output || {}
}
//NOTE: do not load if using the old ui
@@ -187,21 +193,39 @@ if (window?.__COMFYUI_FRONTEND_VERSION__) {
el.parentNode.style.overflowY = 'clip'
}
const urls = await getUrls(currentMode)
const allModes = await getModes()
const input_modes = allModes.input.map((m) => `input - ${m}`)
const output_modes = allModes.output.map((m) => `output - ${m}`)
const urls = await getUrls()
let imgs = {}
const cont = makeElement('div.mtb_sidebar')
const imgGrid = makeElement('div.mtb_img_grid')
const selector = makeSelect(['input', 'output'], currentMode)
const selector = makeSelect(
['input', 'output', ...output_modes, ...input_modes],
currentMode,
)
selector.addEventListener('change', async (e) => {
const newMode = e.target.value
const changed = newMode !== currentMode
let newMode = e.target.value
let changed = false
let newSub = ''
if (newMode !== 'input' || newMode !== 'output') {
if (newMode.startsWith('input - ')) {
newSub = newMode.replace('input - ', '')
newMode = 'input'
} else {
newSub = newMode.replace('output - ', '')
newMode = 'output'
}
}
changed = newMode !== currentMode || newSub !== subfolder
currentMode = newMode
subfolder = newSub
if (changed) {
imgGrid.innerHTML = ''
const urls = await getUrls()
const urls = await getUrls(subfolder)
if (urls) {
imgs = getImgsFromUrls(urls, imgGrid)
}
@@ -220,7 +244,7 @@ if (window?.__COMFYUI_FRONTEND_VERSION__) {
currentSort = newSort
if (changed) {
imgGrid.innerHTML = ''
const urls = await getUrls()
const urls = await getUrls(subfolder)
if (urls) {
imgs = getImgsFromUrls(urls, imgGrid)
}
@@ -229,7 +253,6 @@ if (window?.__COMFYUI_FRONTEND_VERSION__) {
const sizeSlider = makeSlider(64, 1024, currentWidth, 1)
imgTools.appendChild(orderSelect)
imgTools.appendChild(sizeSlider)
imgs = getImgsFromUrls(urls, imgGrid)
+10 -20
View File
@@ -672,8 +672,7 @@ const mtb_widgets = {
init: async () => {
infoLogger('Registering mtb.widgets')
try {
const res = await api.fetchApi('/mtb/server-info')
const msg = await res.json()
const msg = await shared.getServerInfo()
if (!window.MTB) {
window.MTB = {}
}
@@ -716,17 +715,11 @@ const mtb_widgets = {
infoLogger('Enabled DEBUG mode')
}
await api
.fetchApi('/mtb/server-info', {
method: 'POST',
body: JSON.stringify({
debug: value,
}),
})
.then((_response) => {})
.catch((error) => {
console.error('Error:', error)
})
try {
shared.setServerInfo({ debug: value })
} catch (err) {
console.error('Error:', err)
}
},
})
},
@@ -1109,13 +1102,10 @@ const mtb_widgets = {
const getStyle = async (node) => {
try {
const getStyles = await api.fetchApi('/mtb/actions', {
method: 'POST',
body: JSON.stringify({
name: 'getStyles',
args: node.widgets?.[0].value ? node.widgets[0].value : '',
}),
})
const getStyles = await runAction(
'getStyles',
node.widgets?.[0].value ? node.widgets[0].value : '',
)
const output = await getStyles.json()
return output?.result