diff --git a/py/manager.py b/py/manager.py
index 0325105..2d7db27 100644
--- a/py/manager.py
+++ b/py/manager.py
@@ -124,41 +124,43 @@ class ModelManager:
if not prefix_path.endswith("/"):
prefix_path = f"{prefix_path}/"
- fullname = utils.normalize_path(entry.path).replace(prefix_path, "")
- basename = os.path.splitext(fullname)[0]
- extension = os.path.splitext(fullname)[1]
+ relative_path = utils.normalize_path(entry.path).replace(prefix_path, "")
+ sub_folder = os.path.dirname(relative_path)
+ filename = os.path.basename(relative_path)
+ basename = os.path.splitext(filename)[0]
+ extension = os.path.splitext(filename)[1]
- if extension not in folder_paths.supported_pt_extensions:
+ is_file = entry.is_file()
+ if is_file and extension not in folder_paths.supported_pt_extensions:
return None
- model_preview = f"/model-manager/preview/{folder}/{path_index}/{basename}.webp"
+ model_preview = f"/model-manager/preview/{folder}/{path_index}/{relative_path.replace(extension, '.webp')}"
stat = entry.stat()
return {
- "fullname": fullname,
+ "type": folder if is_file else "folder",
+ "subFolder": sub_folder,
"basename": basename,
"extension": extension,
- "type": folder,
"pathIndex": path_index,
- "sizeBytes": stat.st_size,
- "preview": model_preview,
+ "sizeBytes": stat.st_size if is_file else 0,
+ "preview": model_preview if is_file else None,
"createdAt": round(stat.st_ctime_ns / 1000000),
"updatedAt": round(stat.st_mtime_ns / 1000000),
}
def get_all_files_entry(directory: str):
- files = []
+ entries: list[os.DirEntry[str]] = []
with os.scandir(directory) as it:
for entry in it:
# Skip hidden files
if not include_hidden_files:
if entry.name.startswith("."):
continue
+ entries.append(entry)
if entry.is_dir():
- files.extend(get_all_files_entry(entry.path))
- elif entry.is_file():
- files.append(entry)
- return files
+ entries.extend(get_all_files_entry(entry.path))
+ return entries
for path_index, base_path in enumerate(folders):
if not os.path.exists(base_path):
diff --git a/src/App.vue b/src/App.vue
index 4d0c8c9..2954a21 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -7,6 +7,7 @@
diff --git a/src/components/DialogManager.vue b/src/components/DialogManager.vue
index dfd39db..e0942ba 100644
--- a/src/components/DialogManager.vue
+++ b/src/components/DialogManager.vue
@@ -49,7 +49,56 @@
v-for="model in item.row"
:key="genModelKey(model)"
:model="model"
- >
+ :style="{
+ width: `${cardSize.width}px`,
+ height: `${cardSize.height}px`,
+ }"
+ class="group/card cursor-pointer !p-0"
+ @click="openModelDetail(model)"
+ v-tooltip.top="{ value: model.basename, disabled: showModelName }"
+ >
+
+
+
+
+ {{ model.basename }}
+
+
+
+
+
+
+
+
+
@@ -72,8 +121,9 @@ import ResponseScroll from 'components/ResponseScroll.vue'
import ResponseSelect from 'components/ResponseSelect.vue'
import { configSetting, useConfig } from 'hooks/config'
import { useContainerQueries } from 'hooks/container'
-import { useModels } from 'hooks/model'
+import { useModelNodeAction, useModels } from 'hooks/model'
import { chunk } from 'lodash'
+import Button from 'primevue/button'
import { app } from 'scripts/comfyAPI'
import { Model } from 'types/typings'
import { genModelKey } from 'utils/model'
@@ -89,7 +139,7 @@ const {
dialog: settings,
} = useConfig()
-const { data, folders } = useModels()
+const { data, folders, openModelDetail } = useModels()
const { t } = useI18n()
const toolbarContainer = ref(null)
@@ -165,12 +215,15 @@ const cols = computed(() => {
const list = computed(() => {
const mergedList = Object.values(data.value).flat()
+ const pureModels = mergedList.filter((item) => {
+ return item.type !== 'folder'
+ })
- const filterList = mergedList.filter((model) => {
+ const filterList = pureModels.filter((model) => {
const showAllModel = currentType.value === allType
const matchType = showAllModel || model.type === currentType.value
- const matchName = model.fullname
+ const matchName = model.basename
.toLowerCase()
.includes(searchContent.value?.toLowerCase() || '')
@@ -180,7 +233,7 @@ const list = computed(() => {
let sortStrategy: (a: Model, b: Model) => number = () => 0
switch (sortOrder.value) {
case 'name':
- sortStrategy = (a, b) => a.fullname.localeCompare(b.fullname)
+ sortStrategy = (a, b) => a.basename.localeCompare(b.basename)
break
case 'size':
sortStrategy = (a, b) => b.sizeBytes - a.sizeBytes
@@ -231,4 +284,15 @@ const cardSizeOptions = computed(() => {
}
})
})
+
+const showModelName = computed(() => {
+ return cardSize.value.width > 120 && cardSize.value.height > 160
+})
+
+const showModeAction = computed(() => {
+ return cardSize.value.width > 120 && cardSize.value.height > 160
+})
+
+const { addModelNode, copyModelNode, loadPreviewWorkflow } =
+ useModelNodeAction()
diff --git a/src/components/DialogModelDetail.vue b/src/components/DialogModelDetail.vue
index d51cf38..80aca01 100644
--- a/src/components/DialogModelDetail.vue
+++ b/src/components/DialogModelDetail.vue
@@ -18,12 +18,18 @@
icon="pi pi-eye"
@click="openModelPage(metadata.modelPage)"
>
-
-
+
+