Refactor showcase checkpoint

This commit is contained in:
Will Miao
2025-02-19 12:53:09 +08:00
parent 1d0af7f163
commit 2f099325e4
3 changed files with 102 additions and 6 deletions

View File

@@ -666,10 +666,17 @@ body.modal-open {
justify-content: center;
gap: 8px;
margin-bottom: var(--space-2);
transition: background-color 0.2s, transform 0.2s;
}
.scroll-indicator:hover {
background: oklch(var(--lora-accent) / 0.1);
transform: translateY(-1px);
}
.scroll-indicator span {
font-size: 0.9em;
color: var(--text-color);
}
.lazy {
@@ -793,4 +800,40 @@ body.modal-open {
.info-item.notes {
grid-column: 1 / -1;
}
}
/* 修改 back-to-top 按钮样式,使其固定在 modal 内部 */
.modal-content .back-to-top {
position: sticky; /* 改用 sticky 定位 */
float: right; /* 使用 float 确保按钮在右侧 */
bottom: 20px; /* 距离底部的距离 */
margin-right: 20px; /* 右侧间距 */
margin-top: -56px; /* 负边距确保不占用额外空间 */
width: 36px;
height: 36px;
border-radius: 50%;
background: var(--card-bg);
border: 1px solid var(--border-color);
color: var(--text-color);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
opacity: 0;
visibility: hidden;
transform: translateY(10px);
transition: all 0.3s ease;
z-index: 10;
}
.modal-content .back-to-top.visible {
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.modal-content .back-to-top:hover {
background: var(--lora-accent);
color: white;
transform: translateY(-2px);
}

View File

@@ -178,6 +178,7 @@ export function showLoraModal(lora) {
modalManager.showModal('loraModal', content);
setupEditableFields();
setupShowcaseScroll(); // Add this line
}
function setupEditableFields() {
@@ -271,7 +272,7 @@ function renderShowcaseImages(images) {
<div class="showcase-section">
<div class="scroll-indicator" onclick="toggleShowcase(this)">
<i class="fas fa-chevron-down"></i>
<span>Show ${images.length} examples</span>
<span>Scroll or click to show ${images.length} examples</span>
</div>
<div class="carousel collapsed">
<div class="carousel-container">
@@ -315,6 +316,9 @@ function renderShowcaseImages(images) {
}).join('')}
</div>
</div>
<button class="back-to-top" onclick="scrollToTop(this)">
<i class="fas fa-arrow-up"></i>
</button>
</div>
`;
}
@@ -329,18 +333,19 @@ export function toggleShowcase(element) {
carousel.classList.toggle('collapsed');
if (isCollapsed) {
indicator.textContent = 'Hide examples';
const count = carousel.querySelectorAll('.media-wrapper').length;
indicator.textContent = `Scroll or click to hide examples`;
icon.classList.replace('fa-chevron-down', 'fa-chevron-up');
initLazyLoading(carousel);
} else {
const count = carousel.querySelectorAll('.media-wrapper').length;
indicator.textContent = `Show ${count} examples`;
indicator.textContent = `Scroll or click to show ${count} examples`;
icon.classList.replace('fa-chevron-up', 'fa-chevron-down');
}
};
// Add lazy loading initialization
export function initLazyLoading(container) {
function initLazyLoading(container) {
const lazyElements = container.querySelectorAll('.lazy');
const lazyLoad = (element) => {
@@ -364,4 +369,52 @@ export function initLazyLoading(container) {
});
lazyElements.forEach(element => observer.observe(element));
}
export function setupShowcaseScroll() {
// Change from modal-content to window/document level
document.addEventListener('wheel', (event) => {
const modalContent = document.querySelector('.modal-content');
if (!modalContent) return;
const showcase = modalContent.querySelector('.showcase-section');
if (!showcase) return;
const carousel = showcase.querySelector('.carousel');
const scrollIndicator = showcase.querySelector('.scroll-indicator');
if (carousel?.classList.contains('collapsed') && event.deltaY > 0) {
const isNearBottom = modalContent.scrollHeight - modalContent.scrollTop - modalContent.clientHeight < 100;
if (isNearBottom) {
toggleShowcase(scrollIndicator);
event.preventDefault();
}
}
});
// Keep the existing scroll tracking code
const modalContent = document.querySelector('.modal-content');
if (modalContent) {
modalContent.addEventListener('scroll', () => {
const backToTopBtn = modalContent.querySelector('.back-to-top');
if (backToTopBtn) {
if (modalContent.scrollTop > 300) {
backToTopBtn.classList.add('visible');
} else {
backToTopBtn.classList.remove('visible');
}
}
});
}
}
export function scrollToTop(button) {
const modalContent = button.closest('.modal-content');
if (modalContent) {
modalContent.scrollTo({
top: 0,
behavior: 'smooth'
});
}
}

View File

@@ -2,7 +2,7 @@ import { debounce } from './utils/debounce.js';
import { LoadingManager } from './managers/LoadingManager.js';
import { modalManager } from './managers/ModalManager.js';
import { state } from './state/index.js';
import { showLoraModal, toggleShowcase, initLazyLoading } from './components/LoraCard.js';
import { showLoraModal, toggleShowcase, scrollToTop } from './components/LoraCard.js';
import { loadMoreLoras, fetchCivitai, deleteModel, replacePreview, resetAndReload, refreshLoras } from './api/loraApi.js';
import {
showToast,
@@ -46,6 +46,7 @@ window.settingsManager = new SettingsManager();
window.toggleApiKeyVisibility = toggleApiKeyVisibility;
window.moveManager = moveManager;
window.toggleShowcase = toggleShowcase;
window.scrollToTop = scrollToTop;
// Initialize everything when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
@@ -59,7 +60,6 @@ document.addEventListener('DOMContentLoaded', () => {
initTheme();
initFolderTagsVisibility();
initBackToTop();
initLazyLoading();
window.searchManager = new SearchManager();
new LoraContextMenu();
});