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 }" + > + + + +
@@ -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)" > - - + + + + +
+
+ + + +
+
+ + +
+
+
+