mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-06-13 14:09:25 -03:00
feat(sidebar): add per-page hide toggle with more options dropdown
- Add ``` button in sidebar header with dropdown menu - Add "Hide sidebar on this page" option with per-page localStorage state - Show edge indicator (14px chevron) on left when hidden per-page - Show brief toast notification when hiding - Fix container margin not resetting when sidebar is per-page hidden - Add i18n translations for all 10 locales
This commit is contained in:
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "Stammverzeichnis",
|
"modelRoot": "Stammverzeichnis",
|
||||||
|
"moreOptions": "Weitere Optionen",
|
||||||
"collapseAll": "Alle Ordner einklappen",
|
"collapseAll": "Alle Ordner einklappen",
|
||||||
"pinSidebar": "Sidebar anheften",
|
"pinSidebar": "Sidebar anheften",
|
||||||
"unpinSidebar": "Sidebar lösen",
|
"unpinSidebar": "Sidebar lösen",
|
||||||
|
"hideOnThisPage": "Seitenleiste auf dieser Seite ausblenden",
|
||||||
|
"showSidebar": "Seitenleiste anzeigen",
|
||||||
|
"sidebarHiddenNotification": "Seitenleiste auf der Seite {page} ausgeblendet",
|
||||||
"switchToListView": "Zur Listenansicht wechseln",
|
"switchToListView": "Zur Listenansicht wechseln",
|
||||||
"switchToTreeView": "Zur Baumansicht wechseln",
|
"switchToTreeView": "Zur Baumansicht wechseln",
|
||||||
"recursiveOn": "Unterordner einbeziehen",
|
"recursiveOn": "Unterordner einbeziehen",
|
||||||
|
|||||||
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "Root",
|
"modelRoot": "Root",
|
||||||
|
"moreOptions": "More options",
|
||||||
"collapseAll": "Collapse All Folders",
|
"collapseAll": "Collapse All Folders",
|
||||||
"pinSidebar": "Pin Sidebar",
|
"pinSidebar": "Pin Sidebar",
|
||||||
"unpinSidebar": "Unpin Sidebar",
|
"unpinSidebar": "Unpin Sidebar",
|
||||||
|
"hideOnThisPage": "Hide sidebar on this page",
|
||||||
|
"showSidebar": "Show sidebar",
|
||||||
|
"sidebarHiddenNotification": "Folder sidebar hidden on {page} page",
|
||||||
"switchToListView": "Switch to List View",
|
"switchToListView": "Switch to List View",
|
||||||
"switchToTreeView": "Switch to Tree View",
|
"switchToTreeView": "Switch to Tree View",
|
||||||
"recursiveOn": "Include subfolders",
|
"recursiveOn": "Include subfolders",
|
||||||
|
|||||||
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "Raíz",
|
"modelRoot": "Raíz",
|
||||||
|
"moreOptions": "Más opciones",
|
||||||
"collapseAll": "Colapsar todas las carpetas",
|
"collapseAll": "Colapsar todas las carpetas",
|
||||||
"pinSidebar": "Fijar barra lateral",
|
"pinSidebar": "Fijar barra lateral",
|
||||||
"unpinSidebar": "Desfijar barra lateral",
|
"unpinSidebar": "Desfijar barra lateral",
|
||||||
|
"hideOnThisPage": "Ocultar barra lateral en esta página",
|
||||||
|
"showSidebar": "Mostrar barra lateral",
|
||||||
|
"sidebarHiddenNotification": "Barra lateral oculta en la página {page}",
|
||||||
"switchToListView": "Cambiar a vista de lista",
|
"switchToListView": "Cambiar a vista de lista",
|
||||||
"switchToTreeView": "Cambiar a vista de árbol",
|
"switchToTreeView": "Cambiar a vista de árbol",
|
||||||
"recursiveOn": "Incluir subcarpetas",
|
"recursiveOn": "Incluir subcarpetas",
|
||||||
|
|||||||
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "Racine",
|
"modelRoot": "Racine",
|
||||||
|
"moreOptions": "Plus d'options",
|
||||||
"collapseAll": "Réduire tous les dossiers",
|
"collapseAll": "Réduire tous les dossiers",
|
||||||
"pinSidebar": "Épingler la barre latérale",
|
"pinSidebar": "Épingler la barre latérale",
|
||||||
"unpinSidebar": "Désépingler la barre latérale",
|
"unpinSidebar": "Désépingler la barre latérale",
|
||||||
|
"hideOnThisPage": "Masquer la barre latérale sur cette page",
|
||||||
|
"showSidebar": "Afficher la barre latérale",
|
||||||
|
"sidebarHiddenNotification": "Barre latérale masquée sur la page {page}",
|
||||||
"switchToListView": "Passer en vue liste",
|
"switchToListView": "Passer en vue liste",
|
||||||
"switchToTreeView": "Passer en vue arborescence",
|
"switchToTreeView": "Passer en vue arborescence",
|
||||||
"recursiveOn": "Inclure les sous-dossiers",
|
"recursiveOn": "Inclure les sous-dossiers",
|
||||||
|
|||||||
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "שורש",
|
"modelRoot": "שורש",
|
||||||
|
"moreOptions": "אפשרויות נוספות",
|
||||||
"collapseAll": "כווץ את כל התיקיות",
|
"collapseAll": "כווץ את כל התיקיות",
|
||||||
"pinSidebar": "נעל סרגל צד",
|
"pinSidebar": "נעל סרגל צד",
|
||||||
"unpinSidebar": "שחרר סרגל צד",
|
"unpinSidebar": "שחרר סרגל צד",
|
||||||
|
"hideOnThisPage": "הסתר סרגל צד בדף זה",
|
||||||
|
"showSidebar": "הצג סרגל צד",
|
||||||
|
"sidebarHiddenNotification": "סרגל הצד מוסתר בדף {page}",
|
||||||
"switchToListView": "עבור לתצוגת רשימה",
|
"switchToListView": "עבור לתצוגת רשימה",
|
||||||
"switchToTreeView": "תצוגת עץ",
|
"switchToTreeView": "תצוגת עץ",
|
||||||
"recursiveOn": "כלול תיקיות משנה",
|
"recursiveOn": "כלול תיקיות משנה",
|
||||||
|
|||||||
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "ルート",
|
"modelRoot": "ルート",
|
||||||
|
"moreOptions": "その他のオプション",
|
||||||
"collapseAll": "すべてのフォルダを折りたたむ",
|
"collapseAll": "すべてのフォルダを折りたたむ",
|
||||||
"pinSidebar": "サイドバーを固定",
|
"pinSidebar": "サイドバーを固定",
|
||||||
"unpinSidebar": "サイドバーの固定を解除",
|
"unpinSidebar": "サイドバーの固定を解除",
|
||||||
|
"hideOnThisPage": "このページでサイドバーを非表示",
|
||||||
|
"showSidebar": "サイドバーを表示",
|
||||||
|
"sidebarHiddenNotification": "{page}ページでサイドバーが非表示になっています",
|
||||||
"switchToListView": "リストビューに切り替え",
|
"switchToListView": "リストビューに切り替え",
|
||||||
"switchToTreeView": "ツリー表示に切り替え",
|
"switchToTreeView": "ツリー表示に切り替え",
|
||||||
"recursiveOn": "サブフォルダーを含める",
|
"recursiveOn": "サブフォルダーを含める",
|
||||||
|
|||||||
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "루트",
|
"modelRoot": "루트",
|
||||||
|
"moreOptions": "더 많은 옵션",
|
||||||
"collapseAll": "모든 폴더 접기",
|
"collapseAll": "모든 폴더 접기",
|
||||||
"pinSidebar": "사이드바 고정",
|
"pinSidebar": "사이드바 고정",
|
||||||
"unpinSidebar": "사이드바 고정 해제",
|
"unpinSidebar": "사이드바 고정 해제",
|
||||||
|
"hideOnThisPage": "이 페이지에서 사이드바 숨기기",
|
||||||
|
"showSidebar": "사이드바 표시",
|
||||||
|
"sidebarHiddenNotification": "{page} 페이지에서 사이드바가 숨겨져 있습니다",
|
||||||
"switchToListView": "목록 보기로 전환",
|
"switchToListView": "목록 보기로 전환",
|
||||||
"switchToTreeView": "트리 보기로 전환",
|
"switchToTreeView": "트리 보기로 전환",
|
||||||
"recursiveOn": "하위 폴더 포함",
|
"recursiveOn": "하위 폴더 포함",
|
||||||
|
|||||||
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "Корень",
|
"modelRoot": "Корень",
|
||||||
|
"moreOptions": "Дополнительные параметры",
|
||||||
"collapseAll": "Свернуть все папки",
|
"collapseAll": "Свернуть все папки",
|
||||||
"pinSidebar": "Закрепить боковую панель",
|
"pinSidebar": "Закрепить боковую панель",
|
||||||
"unpinSidebar": "Открепить боковую панель",
|
"unpinSidebar": "Открепить боковую панель",
|
||||||
|
"hideOnThisPage": "Скрыть боковую панель на этой странице",
|
||||||
|
"showSidebar": "Показать боковую панель",
|
||||||
|
"sidebarHiddenNotification": "Боковая панель скрыта на странице {page}",
|
||||||
"switchToListView": "Переключить на вид списка",
|
"switchToListView": "Переключить на вид списка",
|
||||||
"switchToTreeView": "Переключить на древовидный вид",
|
"switchToTreeView": "Переключить на древовидный вид",
|
||||||
"recursiveOn": "Включать вложенные папки",
|
"recursiveOn": "Включать вложенные папки",
|
||||||
|
|||||||
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "根目录",
|
"modelRoot": "根目录",
|
||||||
|
"moreOptions": "更多选项",
|
||||||
"collapseAll": "折叠所有文件夹",
|
"collapseAll": "折叠所有文件夹",
|
||||||
"pinSidebar": "固定侧边栏",
|
"pinSidebar": "固定侧边栏",
|
||||||
"unpinSidebar": "取消固定侧边栏",
|
"unpinSidebar": "取消固定侧边栏",
|
||||||
|
"hideOnThisPage": "隐藏此页面侧边栏",
|
||||||
|
"showSidebar": "显示侧边栏",
|
||||||
|
"sidebarHiddenNotification": "{page}页面的文件夹侧边栏已隐藏",
|
||||||
"switchToListView": "切换到列表视图",
|
"switchToListView": "切换到列表视图",
|
||||||
"switchToTreeView": "切换到树状视图",
|
"switchToTreeView": "切换到树状视图",
|
||||||
"recursiveOn": "包含子文件夹",
|
"recursiveOn": "包含子文件夹",
|
||||||
|
|||||||
@@ -953,9 +953,13 @@
|
|||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"modelRoot": "根目錄",
|
"modelRoot": "根目錄",
|
||||||
|
"moreOptions": "更多選項",
|
||||||
"collapseAll": "全部摺疊資料夾",
|
"collapseAll": "全部摺疊資料夾",
|
||||||
"pinSidebar": "固定側邊欄",
|
"pinSidebar": "固定側邊欄",
|
||||||
"unpinSidebar": "取消固定側邊欄",
|
"unpinSidebar": "取消固定側邊欄",
|
||||||
|
"hideOnThisPage": "隱藏此頁面側邊欄",
|
||||||
|
"showSidebar": "顯示側邊欄",
|
||||||
|
"sidebarHiddenNotification": "{page}頁面的資料夾側邊欄已隱藏",
|
||||||
"switchToListView": "切換至列表檢視",
|
"switchToListView": "切換至列表檢視",
|
||||||
"switchToTreeView": "切換到樹狀檢視",
|
"switchToTreeView": "切換到樹狀檢視",
|
||||||
"recursiveOn": "包含子資料夾",
|
"recursiveOn": "包含子資料夾",
|
||||||
|
|||||||
@@ -84,6 +84,7 @@
|
|||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: var(--transition-base);
|
transition: var(--transition-base);
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-header:hover {
|
.sidebar-header:hover {
|
||||||
@@ -150,6 +151,120 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ===== Sidebar More Options Dropdown ===== */
|
||||||
|
.sidebar-more-dropdown {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
right: 8px;
|
||||||
|
min-width: 190px;
|
||||||
|
background: var(--bg-color);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: var(--border-radius-xs);
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
z-index: calc(var(--z-overlay) + 20);
|
||||||
|
display: none;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-more-dropdown.open {
|
||||||
|
display: block;
|
||||||
|
animation: dropdownFadeIn 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes dropdownFadeIn {
|
||||||
|
from { opacity: 0; transform: translateY(-4px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-dropdown-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 0.85em;
|
||||||
|
color: var(--text-color);
|
||||||
|
transition: var(--transition-base);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-dropdown-item:hover {
|
||||||
|
background: var(--lora-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-dropdown-item i {
|
||||||
|
width: 16px;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 0.9em;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-dropdown-item:hover i {
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-dropdown-item.disabled {
|
||||||
|
opacity: 0.4;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Sidebar Hidden Indicator (left edge) ===== */
|
||||||
|
.sidebar-hidden-indicator {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
z-index: var(--z-overlay);
|
||||||
|
width: 14px;
|
||||||
|
height: 44px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: var(--border-color);
|
||||||
|
opacity: 0.3;
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.15s ease, background 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-hidden-indicator:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
background: var(--lora-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-hidden-indicator i {
|
||||||
|
font-size: 9px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
transition: color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-hidden-indicator:hover i {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-hidden-indicator-tooltip {
|
||||||
|
position: absolute;
|
||||||
|
left: 100%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
margin-left: 8px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
background: var(--text-color);
|
||||||
|
color: var(--bg-color);
|
||||||
|
font-size: 0.8em;
|
||||||
|
border-radius: 4px;
|
||||||
|
white-space: nowrap;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-hidden-indicator:hover .sidebar-hidden-indicator-tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebar-content {
|
.sidebar-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ export class SidebarManager {
|
|||||||
this.currentDropTarget = null;
|
this.currentDropTarget = null;
|
||||||
this.lastPageControls = null;
|
this.lastPageControls = null;
|
||||||
this.isDisabledBySetting = false;
|
this.isDisabledBySetting = false;
|
||||||
|
this.isDisabledByPage = false;
|
||||||
|
this.isMoreDropdownOpen = false;
|
||||||
this.initializationPromise = null;
|
this.initializationPromise = null;
|
||||||
this.isCreatingFolder = false;
|
this.isCreatingFolder = false;
|
||||||
this._pendingDragState = null; // 用于保存拖拽创建文件夹时的状态
|
this._pendingDragState = null; // 用于保存拖拽创建文件夹时的状态
|
||||||
@@ -68,6 +70,10 @@ export class SidebarManager {
|
|||||||
this.handleSidebarDrop = this.handleSidebarDrop.bind(this);
|
this.handleSidebarDrop = this.handleSidebarDrop.bind(this);
|
||||||
this.handleCreateFolderSubmit = this.handleCreateFolderSubmit.bind(this);
|
this.handleCreateFolderSubmit = this.handleCreateFolderSubmit.bind(this);
|
||||||
this.handleCreateFolderCancel = this.handleCreateFolderCancel.bind(this);
|
this.handleCreateFolderCancel = this.handleCreateFolderCancel.bind(this);
|
||||||
|
this.handleMoreToggle = this.handleMoreToggle.bind(this);
|
||||||
|
this.handleMoreDropdownItemClick = this.handleMoreDropdownItemClick.bind(this);
|
||||||
|
this.handleDocumentClickForMore = this.handleDocumentClickForMore.bind(this);
|
||||||
|
this.getPageDisplayName = this.getPageDisplayName.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
setHostPageControls(pageControls) {
|
setHostPageControls(pageControls) {
|
||||||
@@ -100,6 +106,8 @@ export class SidebarManager {
|
|||||||
this.initializeDragAndDrop();
|
this.initializeDragAndDrop();
|
||||||
this.updateSidebarTitle();
|
this.updateSidebarTitle();
|
||||||
this.restoreSidebarState();
|
this.restoreSidebarState();
|
||||||
|
// Re-apply DOM visibility now that per-page state is known
|
||||||
|
this.updateDomVisibility(!this.isDisabledBySetting);
|
||||||
await this.loadFolderTree();
|
await this.loadFolderTree();
|
||||||
if (this.isDisabledBySetting && !forceInitialize) {
|
if (this.isDisabledBySetting && !forceInitialize) {
|
||||||
this.cleanup();
|
this.cleanup();
|
||||||
@@ -143,6 +151,13 @@ export class SidebarManager {
|
|||||||
this.sidebarDragHandlersInitialized = false;
|
this.sidebarDragHandlersInitialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const moreDropdown = document.getElementById('sidebarMoreDropdown');
|
||||||
|
if (moreDropdown) {
|
||||||
|
moreDropdown.classList.remove('open');
|
||||||
|
}
|
||||||
|
this.isMoreDropdownOpen = false;
|
||||||
|
this.hideSidebarHiddenIndicator();
|
||||||
|
|
||||||
// Reset state
|
// Reset state
|
||||||
this.pageControls = null;
|
this.pageControls = null;
|
||||||
this.pageType = null;
|
this.pageType = null;
|
||||||
@@ -151,6 +166,7 @@ export class SidebarManager {
|
|||||||
this.expandedNodes = new Set();
|
this.expandedNodes = new Set();
|
||||||
this.openDropdown = null;
|
this.openDropdown = null;
|
||||||
this.isHovering = false;
|
this.isHovering = false;
|
||||||
|
this.isDisabledByPage = false;
|
||||||
this.apiClient = null;
|
this.apiClient = null;
|
||||||
this.isInitialized = false;
|
this.isInitialized = false;
|
||||||
this.recursiveSearchEnabled = true;
|
this.recursiveSearchEnabled = true;
|
||||||
@@ -217,6 +233,18 @@ export class SidebarManager {
|
|||||||
if (recursiveToggleBtn) {
|
if (recursiveToggleBtn) {
|
||||||
recursiveToggleBtn.removeEventListener('click', this.handleRecursiveToggle);
|
recursiveToggleBtn.removeEventListener('click', this.handleRecursiveToggle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const moreToggle = document.getElementById('sidebarMoreToggle');
|
||||||
|
if (moreToggle) {
|
||||||
|
moreToggle.removeEventListener('click', this.handleMoreToggle);
|
||||||
|
}
|
||||||
|
|
||||||
|
const moreDropdown = document.getElementById('sidebarMoreDropdown');
|
||||||
|
if (moreDropdown) {
|
||||||
|
moreDropdown.removeEventListener('click', this.handleMoreDropdownItemClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.removeEventListener('click', this.handleDocumentClickForMore);
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeDragAndDrop() {
|
initializeDragAndDrop() {
|
||||||
@@ -1045,6 +1073,19 @@ export class SidebarManager {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// More options dropdown
|
||||||
|
const moreToggle = document.getElementById('sidebarMoreToggle');
|
||||||
|
if (moreToggle) {
|
||||||
|
moreToggle.addEventListener('click', this.handleMoreToggle);
|
||||||
|
}
|
||||||
|
|
||||||
|
const moreDropdown = document.getElementById('sidebarMoreDropdown');
|
||||||
|
if (moreDropdown) {
|
||||||
|
moreDropdown.addEventListener('click', this.handleMoreDropdownItemClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('click', this.handleDocumentClickForMore);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDocumentClick(event) {
|
handleDocumentClick(event) {
|
||||||
@@ -1066,6 +1107,7 @@ export class SidebarManager {
|
|||||||
this.isPinned = !this.isPinned;
|
this.isPinned = !this.isPinned;
|
||||||
this.updateAutoHideState();
|
this.updateAutoHideState();
|
||||||
this.updatePinButton();
|
this.updatePinButton();
|
||||||
|
this.updateMoreDropdownLabels();
|
||||||
this.saveSidebarState();
|
this.saveSidebarState();
|
||||||
this.updateContainerMargin();
|
this.updateContainerMargin();
|
||||||
}
|
}
|
||||||
@@ -1129,7 +1171,7 @@ export class SidebarManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateAutoHideState() {
|
updateAutoHideState() {
|
||||||
if (this.isDisabledBySetting) return;
|
if (this.isDisabledBySetting || this.isDisabledByPage) return;
|
||||||
|
|
||||||
const sidebar = document.getElementById('folderSidebar');
|
const sidebar = document.getElementById('folderSidebar');
|
||||||
const hoverArea = document.getElementById('sidebarHoverArea');
|
const hoverArea = document.getElementById('sidebarHoverArea');
|
||||||
@@ -1174,9 +1216,12 @@ export class SidebarManager {
|
|||||||
|
|
||||||
if (!container || !sidebar || this.isDisabledBySetting) return;
|
if (!container || !sidebar || this.isDisabledBySetting) return;
|
||||||
|
|
||||||
// Reset margin to default
|
// Always reset margin first — needed when transitioning from visible to hidden
|
||||||
container.style.marginLeft = '';
|
container.style.marginLeft = '';
|
||||||
|
|
||||||
|
// When per-page disabled, skip adjustment but margin is already reset
|
||||||
|
if (this.isDisabledByPage) return;
|
||||||
|
|
||||||
// Only adjust margin if sidebar is visible and pinned
|
// Only adjust margin if sidebar is visible and pinned
|
||||||
if ((this.isPinned || this.isHovering) && this.isVisible) {
|
if ((this.isPinned || this.isHovering) && this.isVisible) {
|
||||||
const sidebarWidth = sidebar.offsetWidth;
|
const sidebarWidth = sidebar.offsetWidth;
|
||||||
@@ -1193,20 +1238,29 @@ export class SidebarManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateDomVisibility(enabled) {
|
updateDomVisibility(enabled) {
|
||||||
|
// Per-page disable adds on top of global setting
|
||||||
|
const isVisible = enabled && !this.isDisabledByPage;
|
||||||
const sidebar = document.getElementById('folderSidebar');
|
const sidebar = document.getElementById('folderSidebar');
|
||||||
const hoverArea = document.getElementById('sidebarHoverArea');
|
const hoverArea = document.getElementById('sidebarHoverArea');
|
||||||
|
|
||||||
if (sidebar) {
|
if (sidebar) {
|
||||||
sidebar.classList.toggle('hidden-by-setting', !enabled);
|
sidebar.classList.toggle('hidden-by-setting', !isVisible);
|
||||||
sidebar.setAttribute('aria-hidden', (!enabled).toString());
|
sidebar.setAttribute('aria-hidden', (!isVisible).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hoverArea) {
|
if (hoverArea) {
|
||||||
hoverArea.classList.toggle('hidden-by-setting', !enabled);
|
hoverArea.classList.toggle('hidden-by-setting', !isVisible);
|
||||||
if (!enabled) {
|
if (!isVisible) {
|
||||||
hoverArea.classList.add('disabled');
|
hoverArea.classList.add('disabled');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show or hide the "sidebar hidden" notification
|
||||||
|
if (enabled && this.isDisabledByPage) {
|
||||||
|
this.showSidebarHiddenIndicator();
|
||||||
|
} else {
|
||||||
|
this.hideSidebarHiddenIndicator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async setSidebarEnabled(enabled) {
|
async setSidebarEnabled(enabled) {
|
||||||
@@ -1266,6 +1320,133 @@ export class SidebarManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===== More Options Dropdown =====
|
||||||
|
|
||||||
|
handleMoreToggle(event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
const dropdown = document.getElementById('sidebarMoreDropdown');
|
||||||
|
if (!dropdown) return;
|
||||||
|
|
||||||
|
this.isMoreDropdownOpen = !dropdown.classList.contains('open');
|
||||||
|
dropdown.classList.toggle('open', this.isMoreDropdownOpen);
|
||||||
|
this.updateMoreDropdownLabels();
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMoreDropdownItemClick(event) {
|
||||||
|
const item = event.target.closest('.sidebar-dropdown-item');
|
||||||
|
if (!item) return;
|
||||||
|
|
||||||
|
const action = item.dataset.action;
|
||||||
|
if (!action) return;
|
||||||
|
|
||||||
|
const dropdown = document.getElementById('sidebarMoreDropdown');
|
||||||
|
if (dropdown) {
|
||||||
|
dropdown.classList.remove('open');
|
||||||
|
this.isMoreDropdownOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case 'toggle-pin':
|
||||||
|
this.handlePinToggle(event);
|
||||||
|
break;
|
||||||
|
case 'toggle-hide':
|
||||||
|
this.toggleHideOnThisPage();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDocumentClickForMore(event) {
|
||||||
|
const dropdown = document.getElementById('sidebarMoreDropdown');
|
||||||
|
const toggle = document.getElementById('sidebarMoreToggle');
|
||||||
|
if (!dropdown || !toggle) return;
|
||||||
|
|
||||||
|
if (!dropdown.contains(event.target) && !toggle.contains(event.target)) {
|
||||||
|
dropdown.classList.remove('open');
|
||||||
|
this.isMoreDropdownOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMoreDropdownLabels() {
|
||||||
|
const pinLabel = document.getElementById('sidebarMorePinLabel');
|
||||||
|
if (pinLabel) {
|
||||||
|
pinLabel.textContent = this.isPinned
|
||||||
|
? translate('sidebar.unpinSidebar')
|
||||||
|
: translate('sidebar.pinSidebar');
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideItem = document.querySelector('.sidebar-dropdown-item[data-action="toggle-hide"]');
|
||||||
|
if (hideItem) {
|
||||||
|
const hideIcon = hideItem.querySelector('i');
|
||||||
|
const hideLabel = hideItem.querySelector('span');
|
||||||
|
if (this.isDisabledByPage) {
|
||||||
|
hideLabel.textContent = translate('sidebar.showSidebar');
|
||||||
|
if (hideIcon) {
|
||||||
|
hideIcon.className = 'fas fa-eye';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hideLabel.textContent = translate('sidebar.hideOnThisPage');
|
||||||
|
if (hideIcon) {
|
||||||
|
hideIcon.className = 'fas fa-eye-slash';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleHideOnThisPage() {
|
||||||
|
this.isDisabledByPage = !this.isDisabledByPage;
|
||||||
|
setStorageItem(`${this.pageType}_sidebarDisabled`, this.isDisabledByPage);
|
||||||
|
this.updateDomVisibility(!this.isDisabledBySetting);
|
||||||
|
this.updateAutoHideState();
|
||||||
|
this.updateContainerMargin();
|
||||||
|
this.updateMoreDropdownLabels();
|
||||||
|
|
||||||
|
if (!this.isDisabledByPage) {
|
||||||
|
this.hideSidebarHiddenIndicator();
|
||||||
|
} else {
|
||||||
|
showToast(
|
||||||
|
'sidebar.sidebarHiddenNotification',
|
||||||
|
{ page: this.getPageDisplayName() },
|
||||||
|
'info',
|
||||||
|
`Sidebar hidden on ${this.getPageDisplayName()} page`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPageDisplayName() {
|
||||||
|
const names = {
|
||||||
|
loras: 'LoRAs',
|
||||||
|
recipes: 'Recipes',
|
||||||
|
checkpoints: 'Checkpoints',
|
||||||
|
embeddings: 'Embeddings',
|
||||||
|
};
|
||||||
|
return names[this.pageType] || this.pageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
showSidebarHiddenIndicator() {
|
||||||
|
if (document.getElementById('sidebarHiddenIndicator')) return;
|
||||||
|
|
||||||
|
const indicator = document.createElement('div');
|
||||||
|
indicator.id = 'sidebarHiddenIndicator';
|
||||||
|
indicator.className = 'sidebar-hidden-indicator';
|
||||||
|
indicator.innerHTML = `
|
||||||
|
<i class="fas fa-chevron-right"></i>
|
||||||
|
<span class="sidebar-hidden-indicator-tooltip">${translate('sidebar.showSidebar')}</span>
|
||||||
|
`;
|
||||||
|
|
||||||
|
indicator.addEventListener('click', () => {
|
||||||
|
this.toggleHideOnThisPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.body.appendChild(indicator);
|
||||||
|
}
|
||||||
|
|
||||||
|
hideSidebarHiddenIndicator() {
|
||||||
|
const indicator = document.getElementById('sidebarHiddenIndicator');
|
||||||
|
if (indicator) {
|
||||||
|
indicator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async loadFolderTree() {
|
async loadFolderTree() {
|
||||||
try {
|
try {
|
||||||
if (this.displayMode === 'tree') {
|
if (this.displayMode === 'tree') {
|
||||||
@@ -1911,6 +2092,7 @@ export class SidebarManager {
|
|||||||
const expandedPaths = getStorageItem(`${this.pageType}_expandedNodes`, []);
|
const expandedPaths = getStorageItem(`${this.pageType}_expandedNodes`, []);
|
||||||
const displayMode = getStorageItem(`${this.pageType}_displayMode`, 'tree'); // 'tree' or 'list', default to 'tree'
|
const displayMode = getStorageItem(`${this.pageType}_displayMode`, 'tree'); // 'tree' or 'list', default to 'tree'
|
||||||
const recursiveSearchEnabled = getStorageItem(`${this.pageType}_recursiveSearch`, true);
|
const recursiveSearchEnabled = getStorageItem(`${this.pageType}_recursiveSearch`, true);
|
||||||
|
this.isDisabledByPage = getStorageItem(`${this.pageType}_sidebarDisabled`, false);
|
||||||
|
|
||||||
this.isPinned = isPinned;
|
this.isPinned = isPinned;
|
||||||
this.expandedNodes = new Set(expandedPaths);
|
this.expandedNodes = new Set(expandedPaths);
|
||||||
|
|||||||
@@ -18,6 +18,20 @@
|
|||||||
<button class="sidebar-action-btn" id="sidebarPinToggle" title="{{ t('sidebar.unpinSidebar') }}">
|
<button class="sidebar-action-btn" id="sidebarPinToggle" title="{{ t('sidebar.unpinSidebar') }}">
|
||||||
<i class="fas fa-thumbtack"></i>
|
<i class="fas fa-thumbtack"></i>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="sidebar-action-btn" id="sidebarMoreToggle" title="{{ t('sidebar.moreOptions') }}">
|
||||||
|
<i class="fas fa-ellipsis-v"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<!-- Dropdown menu for more options -->
|
||||||
|
<div class="sidebar-more-dropdown" id="sidebarMoreDropdown">
|
||||||
|
<div class="sidebar-dropdown-item" data-action="toggle-pin">
|
||||||
|
<i class="fas fa-thumbtack"></i>
|
||||||
|
<span id="sidebarMorePinLabel">{{ t('sidebar.pinSidebar') }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="sidebar-dropdown-item" data-action="toggle-hide">
|
||||||
|
<i class="fas fa-eye-slash"></i>
|
||||||
|
<span>{{ t('sidebar.hideOnThisPage') }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-content">
|
<div class="sidebar-content">
|
||||||
|
|||||||
Reference in New Issue
Block a user