feat(auto): 已收藏显示
This commit is contained in:
parent
dc23a4abd7
commit
db1208b981
@ -334,6 +334,7 @@ body:has(.reader-mode) #toast {
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
background: var(--bg-hover);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.novel-cover img {
|
||||
@ -342,6 +343,111 @@ body:has(.reader-mode) #toast {
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
/* 书架标识徽章 - 更醒目美观的版本 */
|
||||
.shelf-badge {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
min-width: 28px;
|
||||
height: 28px;
|
||||
padding: 0 8px;
|
||||
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
|
||||
border-radius: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 4px;
|
||||
box-shadow:
|
||||
0 2px 12px rgba(76, 175, 80, 0.4),
|
||||
0 0 0 2px rgba(255, 255, 255, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
z-index: 10;
|
||||
animation: shelfBadgePulse 2.5s ease-in-out infinite;
|
||||
backdrop-filter: blur(4px);
|
||||
will-change: transform, box-shadow;
|
||||
transform: translateZ(0); /* 启用硬件加速 */
|
||||
}
|
||||
|
||||
.shelf-badge::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -2px;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(135deg, rgba(76, 175, 80, 0.3), rgba(69, 160, 73, 0.3));
|
||||
z-index: -1;
|
||||
animation: shelfBadgeGlow 2.5s ease-in-out infinite;
|
||||
will-change: opacity, transform;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
.shelf-badge svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: #ffffff;
|
||||
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.3));
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.shelf-badge-text {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #ffffff;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
white-space: nowrap;
|
||||
display: none; /* 默认隐藏文字,只显示图标 */
|
||||
}
|
||||
|
||||
/* 列表卡片中的书架标识 - 显示文字 */
|
||||
.novel-card .shelf-badge {
|
||||
min-width: auto;
|
||||
padding: 0 6px;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.novel-card .shelf-badge-text {
|
||||
display: inline;
|
||||
font-size: 10px;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
@keyframes shelfBadgePulse {
|
||||
0%, 100% {
|
||||
transform: scale(1) translateZ(0);
|
||||
box-shadow:
|
||||
0 2px 12px rgba(76, 175, 80, 0.4),
|
||||
0 0 0 2px rgba(255, 255, 255, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.05) translateZ(0);
|
||||
box-shadow:
|
||||
0 4px 16px rgba(76, 175, 80, 0.5),
|
||||
0 0 0 3px rgba(255, 255, 255, 0.15),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes shelfBadgeGlow {
|
||||
0%, 100% {
|
||||
opacity: 0.5;
|
||||
transform: scale(1) translateZ(0);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
transform: scale(1.1) translateZ(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* 减少动画以节省电量(可选,用户可启用) */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.shelf-badge {
|
||||
animation: none;
|
||||
}
|
||||
.shelf-badge::before {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
.novel-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
@ -411,6 +517,34 @@ body:has(.reader-mode) #toast {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* 网格卡片中的书架标识 */
|
||||
.novel-grid-card .shelf-badge {
|
||||
top: 6px;
|
||||
right: 6px;
|
||||
min-width: 24px;
|
||||
height: 24px;
|
||||
padding: 0 6px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.novel-grid-card .shelf-badge::before {
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
.novel-grid-card .shelf-badge svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
}
|
||||
|
||||
/* 鼠标悬停时的增强效果(桌面端) */
|
||||
@media (hover: hover) {
|
||||
.novel-card:hover .shelf-badge,
|
||||
.novel-grid-card:hover .shelf-badge {
|
||||
animation: shelfBadgePulse 1s ease-in-out infinite;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
.novel-grid-card .novel-info {
|
||||
padding: var(--spacing-sm);
|
||||
}
|
||||
|
||||
@ -350,6 +350,9 @@ const App = (function() {
|
||||
$btn.find('svg path').attr('d', 'M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z');
|
||||
$btn.contents().last()[0].textContent = '加入书架';
|
||||
Toast.show('已从书架移除');
|
||||
|
||||
// 更新当前页面所有相关书籍卡片的书架标识
|
||||
$(`.novel-card[data-novel-id="${novelId}"] .shelf-badge, .novel-grid-card[data-novel-id="${novelId}"] .shelf-badge`).remove();
|
||||
} else {
|
||||
await API.addToShelf({ userId: Store.getUserId(), novelId });
|
||||
Store.addToShelfCache(novelId);
|
||||
@ -357,6 +360,13 @@ const App = (function() {
|
||||
$btn.find('svg path').attr('d', 'M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z');
|
||||
$btn.contents().last()[0].textContent = '已在书架';
|
||||
Toast.show('已加入书架');
|
||||
|
||||
// 更新当前页面所有相关书籍卡片的书架标识
|
||||
// 列表视图显示文字,网格视图只显示图标
|
||||
const badgeHtmlList = '<div class="shelf-badge" title="已在书架"><svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg><span class="shelf-badge-text">已收藏</span></div>';
|
||||
const badgeHtmlGrid = '<div class="shelf-badge" title="已在书架"><svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg></div>';
|
||||
$(`.novel-card[data-novel-id="${novelId}"] .novel-cover`).append(badgeHtmlList);
|
||||
$(`.novel-grid-card[data-novel-id="${novelId}"] .novel-cover`).append(badgeHtmlGrid);
|
||||
}
|
||||
} catch (error) {
|
||||
Toast.show('操作失败');
|
||||
|
||||
@ -199,10 +199,12 @@ const Pages = (function() {
|
||||
|
||||
let html = '';
|
||||
novels.forEach(novel => {
|
||||
const isInShelf = Store.isInShelfCache(novel.id);
|
||||
html += `
|
||||
<div class="novel-grid-card" data-novel-id="${novel.id}">
|
||||
<div class="novel-cover">
|
||||
<img src="${novel.cover || ''}" alt="${novel.name}" loading="lazy">
|
||||
${isInShelf ? '<div class="shelf-badge" title="已在书架"><svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg></div>' : ''}
|
||||
</div>
|
||||
<div class="novel-info">
|
||||
<div class="novel-title text-ellipsis">${novel.name}</div>
|
||||
@ -285,7 +287,8 @@ const Pages = (function() {
|
||||
|
||||
let html = '';
|
||||
novels.forEach(novel => {
|
||||
html += renderNovelCard(novel);
|
||||
const isInShelf = Store.isInShelfCache(novel.id);
|
||||
html += renderNovelCard(novel, isInShelf);
|
||||
});
|
||||
|
||||
if (append) {
|
||||
@ -316,13 +319,16 @@ const Pages = (function() {
|
||||
}
|
||||
}
|
||||
|
||||
function renderNovelCard(novel) {
|
||||
function renderNovelCard(novel, inShelf = false) {
|
||||
const synopsis = cleanContent(novel.synopsis).substring(0, 80);
|
||||
const tags = (novel.tags || []).slice(0, 2);
|
||||
// 检查书架状态(如果没有传入,则从缓存中检查)
|
||||
const isInShelf = inShelf !== undefined ? inShelf : Store.isInShelfCache(novel.id);
|
||||
return `
|
||||
<div class="novel-card" data-novel-id="${novel.id}">
|
||||
<div class="novel-cover">
|
||||
<img src="${novel.cover || ''}" alt="${novel.name}" loading="lazy">
|
||||
${isInShelf ? '<div class="shelf-badge" title="已在书架"><svg viewBox="0 0 24 24"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg><span class="shelf-badge-text">已收藏</span></div>' : ''}
|
||||
</div>
|
||||
<div class="novel-info">
|
||||
<div class="novel-title text-ellipsis">${novel.name}</div>
|
||||
@ -656,7 +662,8 @@ const Pages = (function() {
|
||||
|
||||
let html = '<div class="novel-list">';
|
||||
novels.forEach(novel => {
|
||||
html += renderNovelCard(novel);
|
||||
const isInShelf = Store.isInShelfCache(novel.id);
|
||||
html += renderNovelCard(novel, isInShelf);
|
||||
});
|
||||
html += '</div>';
|
||||
|
||||
@ -688,7 +695,8 @@ const Pages = (function() {
|
||||
|
||||
let html = '<div class="novel-list">';
|
||||
novels.forEach(novel => {
|
||||
html += renderNovelCard(novel);
|
||||
const isInShelf = Store.isInShelfCache(novel.id);
|
||||
html += renderNovelCard(novel, isInShelf);
|
||||
});
|
||||
html += '</div>';
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user