mirror of
https://github.com/willmiao/ComfyUI-Lora-Manager.git
synced 2026-06-09 20:39:25 -03:00
feat(ui): add adaptive expand/collapse for Additional Notes section (#962)
This commit is contained in:
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "Notizen erfolgreich gespeichert",
|
"saved": "Notizen erfolgreich gespeichert",
|
||||||
"saveFailed": "Fehler beim Speichern der Notizen"
|
"saveFailed": "Fehler beim Speichern der Notizen",
|
||||||
|
"showMore": "Mehr anzeigen",
|
||||||
|
"showLess": "Weniger anzeigen"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "Voreingestellten Parameter hinzufügen...",
|
"addPresetParameter": "Voreingestellten Parameter hinzufügen...",
|
||||||
|
|||||||
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "Notes saved successfully",
|
"saved": "Notes saved successfully",
|
||||||
"saveFailed": "Failed to save notes"
|
"saveFailed": "Failed to save notes",
|
||||||
|
"showMore": "Show more",
|
||||||
|
"showLess": "Show less"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "Add preset parameter...",
|
"addPresetParameter": "Add preset parameter...",
|
||||||
|
|||||||
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "Notas guardadas exitosamente",
|
"saved": "Notas guardadas exitosamente",
|
||||||
"saveFailed": "Error al guardar notas"
|
"saveFailed": "Error al guardar notas",
|
||||||
|
"showMore": "Mostrar más",
|
||||||
|
"showLess": "Mostrar menos"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "Añadir parámetro preestablecido...",
|
"addPresetParameter": "Añadir parámetro preestablecido...",
|
||||||
|
|||||||
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "Notes sauvegardées avec succès",
|
"saved": "Notes sauvegardées avec succès",
|
||||||
"saveFailed": "Échec de la sauvegarde des notes"
|
"saveFailed": "Échec de la sauvegarde des notes",
|
||||||
|
"showMore": "Afficher plus",
|
||||||
|
"showLess": "Afficher moins"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "Ajouter un paramètre prédéfini...",
|
"addPresetParameter": "Ajouter un paramètre prédéfini...",
|
||||||
|
|||||||
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "הערות נשמרו בהצלחה",
|
"saved": "הערות נשמרו בהצלחה",
|
||||||
"saveFailed": "שמירת ההערות נכשלה"
|
"saveFailed": "שמירת ההערות נכשלה",
|
||||||
|
"showMore": "הצג עוד",
|
||||||
|
"showLess": "הצג פחות"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "הוסף פרמטר קבוע מראש...",
|
"addPresetParameter": "הוסף פרמטר קבוע מראש...",
|
||||||
|
|||||||
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "メモが正常に保存されました",
|
"saved": "メモが正常に保存されました",
|
||||||
"saveFailed": "メモの保存に失敗しました"
|
"saveFailed": "メモの保存に失敗しました",
|
||||||
|
"showMore": "もっと見る",
|
||||||
|
"showLess": "折りたたむ"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "プリセットパラメータを追加...",
|
"addPresetParameter": "プリセットパラメータを追加...",
|
||||||
|
|||||||
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "메모가 성공적으로 저장됨",
|
"saved": "메모가 성공적으로 저장됨",
|
||||||
"saveFailed": "메모 저장 실패"
|
"saveFailed": "메모 저장 실패",
|
||||||
|
"showMore": "더 보기",
|
||||||
|
"showLess": "접기"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "프리셋 매개변수 추가...",
|
"addPresetParameter": "프리셋 매개변수 추가...",
|
||||||
|
|||||||
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "Заметки успешно сохранены",
|
"saved": "Заметки успешно сохранены",
|
||||||
"saveFailed": "Не удалось сохранить заметки"
|
"saveFailed": "Не удалось сохранить заметки",
|
||||||
|
"showMore": "Показать больше",
|
||||||
|
"showLess": "Свернуть"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "Добавить предустановленный параметр...",
|
"addPresetParameter": "Добавить предустановленный параметр...",
|
||||||
|
|||||||
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "备注保存成功",
|
"saved": "备注保存成功",
|
||||||
"saveFailed": "备注保存失败"
|
"saveFailed": "备注保存失败",
|
||||||
|
"showMore": "展开",
|
||||||
|
"showLess": "收起"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "添加预设参数...",
|
"addPresetParameter": "添加预设参数...",
|
||||||
|
|||||||
@@ -1225,7 +1225,9 @@
|
|||||||
},
|
},
|
||||||
"notes": {
|
"notes": {
|
||||||
"saved": "備註已儲存",
|
"saved": "備註已儲存",
|
||||||
"saveFailed": "儲存備註失敗"
|
"saveFailed": "儲存備註失敗",
|
||||||
|
"showMore": "展開",
|
||||||
|
"showLess": "收起"
|
||||||
},
|
},
|
||||||
"usageTips": {
|
"usageTips": {
|
||||||
"addPresetParameter": "新增預設參數...",
|
"addPresetParameter": "新增預設參數...",
|
||||||
|
|||||||
@@ -140,14 +140,66 @@
|
|||||||
|
|
||||||
/* Add specific styles for notes content */
|
/* Add specific styles for notes content */
|
||||||
.info-item.notes .editable-field [contenteditable] {
|
.info-item.notes .editable-field [contenteditable] {
|
||||||
height: 60px; /* Keep initial modal layout stable regardless of note length */
|
min-height: 60px;
|
||||||
min-height: 60px; /* Increase height for multiple lines */
|
white-space: pre-wrap;
|
||||||
max-height: 420px; /* Limit maximum height */
|
line-height: 1.5;
|
||||||
overflow: auto; /* Enable scrolling and resize handle for long content */
|
padding: 8px 12px;
|
||||||
resize: vertical; /* Allow manual vertical resizing */
|
}
|
||||||
white-space: pre-wrap; /* Preserve line breaks */
|
|
||||||
line-height: 1.5; /* Improve readability */
|
/* Notes expand/collapse — collapsed by default; only applies when JS detects long content */
|
||||||
padding: 8px 12px; /* Slightly increase padding */
|
.info-item.notes .editable-field {
|
||||||
|
position: relative;
|
||||||
|
max-height: none;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item.notes .editable-field.collapsed {
|
||||||
|
max-height: 80px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gradient fade overlay hint when collapsed */
|
||||||
|
.info-item.notes .editable-field.collapsed::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 28px;
|
||||||
|
background: linear-gradient(transparent, var(--bg-color));
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Notes header row — label left, toggle button right */
|
||||||
|
.notes-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Toggle button — icon only, inline with the label */
|
||||||
|
.notes-toggle-btn {
|
||||||
|
display: none; /* shown by JS when content exceeds threshold */
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
color: var(--lora-accent);
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background 0.15s;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes-toggle-btn:hover {
|
||||||
|
background: rgba(66, 153, 225, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notes-toggle-btn i {
|
||||||
|
font-size: 0.85em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-path {
|
.file-path {
|
||||||
|
|||||||
@@ -510,7 +510,12 @@ export async function showModelModal(model, modelType) {
|
|||||||
</div>
|
</div>
|
||||||
${typeSpecificContent}
|
${typeSpecificContent}
|
||||||
<div class="info-item notes">
|
<div class="info-item notes">
|
||||||
<label>${translate('modals.model.metadata.additionalNotes', {}, 'Additional Notes')} <i class="fas fa-info-circle notes-hint" title="${translate('modals.model.metadata.notesHint', {}, 'Press Enter to save, Shift+Enter for new line')}"></i></label>
|
<div class="notes-header">
|
||||||
|
<label>${translate('modals.model.metadata.additionalNotes', {}, 'Additional Notes')} <i class="fas fa-info-circle notes-hint" title="${translate('modals.model.metadata.notesHint', {}, 'Press Enter to save, Shift+Enter for new line')}"></i></label>
|
||||||
|
<button class="notes-toggle-btn" style="display:none" title="${translate('modals.model.notes.showMore', {}, 'Show more')}">
|
||||||
|
<i class="fas fa-chevron-down"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div class="editable-field">
|
<div class="editable-field">
|
||||||
<div class="notes-content" contenteditable="true" spellcheck="false">${modelWithFullData.notes || translate('modals.model.metadata.addNotesPlaceholder', {}, 'Add your notes here...')}</div>
|
<div class="notes-content" contenteditable="true" spellcheck="false">${modelWithFullData.notes || translate('modals.model.metadata.addNotesPlaceholder', {}, 'Add your notes here...')}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -837,12 +842,70 @@ function setupEditableFields(filePath, modelType) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup adaptive expand/collapse for notes
|
||||||
|
setupNotesExpand();
|
||||||
|
|
||||||
// LoRA specific field setup
|
// LoRA specific field setup
|
||||||
if (modelType === 'loras') {
|
if (modelType === 'loras') {
|
||||||
setupLoraSpecificFields(filePath);
|
setupLoraSpecificFields(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adaptive expand/collapse for the Additional Notes section.
|
||||||
|
* Measures content height synchronously after render (before first paint,
|
||||||
|
* so no visual flash). If notes fit within ~4 lines, no toggle is shown.
|
||||||
|
* If they exceed the threshold, the field collapses with a gradient fade
|
||||||
|
* and a "Show more" button appears.
|
||||||
|
*/
|
||||||
|
function setupNotesExpand() {
|
||||||
|
const notesContainer = document.querySelector('.info-item.notes');
|
||||||
|
if (!notesContainer) return;
|
||||||
|
|
||||||
|
const notesField = notesContainer.querySelector('.editable-field');
|
||||||
|
const notesContent = notesContainer.querySelector('.notes-content');
|
||||||
|
const toggleBtn = notesContainer.querySelector('.notes-toggle-btn');
|
||||||
|
|
||||||
|
if (!notesField || !notesContent || !toggleBtn) return;
|
||||||
|
|
||||||
|
const placeholderText = translate('modals.model.metadata.addNotesPlaceholder', {}, 'Add your notes here...');
|
||||||
|
const content = notesContent.textContent || '';
|
||||||
|
const isEmpty = !content.trim() || content === placeholderText;
|
||||||
|
|
||||||
|
if (isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSS default has no constraints, so scrollHeight reflects full content
|
||||||
|
const contentHeight = notesContent.scrollHeight;
|
||||||
|
const collapsedThreshold = 95; // ~4 lines
|
||||||
|
|
||||||
|
if (contentHeight <= collapsedThreshold) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Long content — collapse and show toggle
|
||||||
|
notesField.classList.add('collapsed');
|
||||||
|
toggleBtn.style.display = 'inline-flex';
|
||||||
|
toggleBtn.title = translate('modals.model.notes.showMore', {}, 'Show more');
|
||||||
|
|
||||||
|
const toggleIcon = toggleBtn.querySelector('i');
|
||||||
|
|
||||||
|
toggleBtn.addEventListener('click', function onClick() {
|
||||||
|
const isCollapsed = notesField.classList.contains('collapsed');
|
||||||
|
if (isCollapsed) {
|
||||||
|
notesField.classList.remove('collapsed');
|
||||||
|
toggleBtn.title = translate('modals.model.notes.showLess', {}, 'Show less');
|
||||||
|
toggleIcon.className = 'fas fa-chevron-up';
|
||||||
|
notesField.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||||||
|
} else {
|
||||||
|
notesField.classList.add('collapsed');
|
||||||
|
toggleBtn.title = translate('modals.model.notes.showMore', {}, 'Show more');
|
||||||
|
toggleIcon.className = 'fas fa-chevron-down';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function setupLoraSpecificFields(filePath) {
|
function setupLoraSpecificFields(filePath) {
|
||||||
const presetSelector = document.getElementById('preset-selector');
|
const presetSelector = document.getElementById('preset-selector');
|
||||||
const presetValue = document.getElementById('preset-value');
|
const presetValue = document.getElementById('preset-value');
|
||||||
|
|||||||
Reference in New Issue
Block a user