Files
ns2.0/templates/explore.html

2190 lines
59 KiB
HTML
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block content %}
<meta name="baidu-site-verification" content="codeva-DExWSnsfeP" />
心愿单通知弹窗
<div id="wishlist-announcement" class="wishlist-announcement">
<div class="announcement-content">
<span class="announcement-text">🎉 APP已上线</span>
<button onclick="window.location.href='https://app.nextmax.cn'" class="goto-btn">前往下载</button>
<button onclick="closeAnnouncement()" class="close-btn">×</button>
</div>
<div class="countdown-bar"></div>
</div>
<!-- QQ群弹窗 -->
<div id="qq-modal" class="modal" style="display: none;">
<div class="modal-content">
<div class="modal-header">
<span class="close" onclick="closeQQModal()">&times;</span>
<h3>QQ交流群</h3>
</div>
<div class="modal-body">
{% if settings.qq_group_qrcode %}
<img src="{{ settings.qq_group_qrcode }}" alt="QQ群二维码" class="qr-code" cache="force-cache" loading="lazy">
{% endif %}
<div class="group-number-container">
<p class="group-number">{{ settings.qq_group_number }}</p>
<button class="copy-btn" onclick="copyGroupNumber()" title="复制群号">
<i class="far fa-copy"></i>
</button>
</div>
<div id="copy-notification" class="copy-notification">
群号已复制到剪贴板
</div>
<div class="join-btn-container">
<a href="{{ settings.qq_group_link }}" class="join-btn qq-join-btn" target="_blank" >
<i class="fab fa-qq"></i>
立即加入
</a>
</div>
</div>
</div>
</div>
<!-- 微信群弹窗 -->
<div id="wechat-modal" class="modal" style="display: none;">
<div class="modal-content">
<div class="modal-header">
<span class="close" onclick="closeWeChatModal()">&times;</span>
<h3>微信交流群</h3>
</div>
<div class="modal-body">
{% if settings.wechat_group_qrcode %}
<img src="{{ settings.wechat_group_qrcode }}" alt="微信群二维码" class="qr-code" cache="force-cache" loading="lazy">
{% endif %}
<p class="group-tip">请扫码加入微信群</p>
</div>
</div>
</div>
<!-- 充电弹窗 -->
<div id="donate-modal" class="modal" style="display: none;">
<div class="modal-content donate-modal">
<div class="modal-header">
<span class="close" onclick="closeDonateModal()">&times;</span>
<h3>赞赏支持</h3>
</div>
<div class="modal-body">
<div class="donate-container">
<p class="donate-text">{{ settings.donate_text }}</p>
{% if settings.donate_image %}
<img src="{{ settings.donate_image }}" alt="赞赏码" class="donate-qr" cache="force-cache" loading="lazy">
{% endif %}
<p class="donate-note" style="color: rgb(201, 180, 60);"><a href="{{ url_for('donors_page') }}" style="color: inherit; text-decoration: underline;">{{ settings.donate_note }}</a></p>
</div>
</div>
</div>
</div>
<!-- 网站标题区域 -->
<header class="site-header">
<div class="site-title">
<h1>探索</h1>
</div>
<nav class="header-actions">
{% if settings.donate_enabled == '1' %}
<div class="donate-new-button" onclick="showDonateModal()">
<button type="button" class="button">
<span class="fold"></span>
<div class="points_wrapper">
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
<i class="point"></i>
</div>
<span class="inner">
<svg class="icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5">
<polyline points="13.18 1.37 13.18 9.64 21.45 9.64 10.82 22.63 10.82 14.36 2.55 14.36 13.18 1.37"></polyline>
</svg>
充电
</span>
</button>
</div>
{% endif %}
</nav>
</header>
<main class="explore-container">
<!-- 新增:抖音关注按钮 -->
<div class="douyin-follow-container">
<a href="https://v.douyin.com/ifrkx5bC/" target="_blank" class="douyin-follow-btn">
<svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg" class="douyin-icon">
<path d="M21.358 19.1399C15.4694 18.8558 11.3762 20.9553 9.07838 25.4384C5.63169 32.163 8.48026 43.1666 19.9788 43.1666C31.4774 43.1666 31.81 32.0554 31.81 30.8914C31.81 30.1154 31.81 25.7764 31.81 17.8746C34.2694 19.4323 36.343 20.37 38.0308 20.6877C39.7186 21.0053 40.7915 21.1461 41.2497 21.11V14.6343C39.6886 14.4461 38.3386 14.0873 37.1997 13.5581C35.4913 12.7643 32.1037 10.5611 32.1037 7.33208C32.106 7.34787 32.106 6.51493 32.1037 4.83325H24.9857C24.9645 20.6493 24.9645 29.3353 24.9857 30.8914C25.0175 33.2255 23.2068 36.4905 19.5355 36.4905C15.8642 36.4905 14.0535 33.2281 14.0535 31.1239C14.0535 29.8357 14.496 27.9685 16.3251 26.5858C17.4098 25.7658 18.9153 25.4384 21.358 25.4384C21.358 24.6828 21.358 22.5833 21.358 19.1399Z" fill="none" stroke="#fff" stroke-width="4" stroke-linejoin="round"/>
</svg>
NEXT Store官方抖音
</a>
</div>
<section class="explore-grid">
<!-- 左侧:新应用卡片 -->
<article class="explore-item fixed-size" onclick="window.location.href='{{ url_for('new_apps') }}';">
<img data-src="{{ url_for('static', filename='new.png') }}"
alt="探索图片1"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
loading="lazy"
data-light-src="{{ url_for('static', filename='new.png') }}"
data-dark-src="{{ url_for('static', filename='newdark.png') }}"
cache="force-cache">
<div class="new-apps-bar">
<div class="apps-row">
{% if today_apps %}
{% for app in today_apps %}
<div class="app-card" onclick="handleAppClick(event, {{ app.id }});">
<div class="app-icon">
{% if 'http' in app.icon_path %}
<img data-src="{{ app.icon_path }}" alt="{{ app.name }}"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
loading="lazy"
cache="force-cache">
{% else %}
<img data-src="{{ url_for('static', filename='uploads/' + app.icon_path) }}"
alt="{{ app.name }}"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
loading="lazy"
cache="force-cache">
{% endif %}
</div>
<div class="app-info">
<h3>{{ app.name }}</h3>
</div>
</div>
{% endfor %}
{% else %}
<div class="no-apps-message">今日暂无新应用</div>
{% endif %}
</div>
</div>
</article>
<article class="explore-item fixed-size" onclick="window.open('https://consumer.huawei.com/cn/harmonyos-computer/harmonyos-5/', '_blank');">
<img data-src="{{ url_for('static', filename='pc-harmonyos5.png') }}"
alt="鸿蒙操作系统5"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
loading="lazy"
data-light-src="{{ url_for('static', filename='pc-harmonyos5.png') }}"
cache="force-cache">
</article>
<!-- 中间:即将上线卡片 -->
<article class="explore-item fixed-size" onclick="window.location.href='{{ url_for('coming') }}';">
<img data-src="{{ url_for('static', filename='coming.png') }}"
alt="探索图片2"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
loading="lazy"
cache="force-cache">
</article>
<!-- 右侧:热门应用区域 -->
<section class="hot-apps-section">
<div class="section-header">
<div class="section-title">
<h2>热门应用</h2>
</div>
<a href="{{ url_for('hot_apps') }}" class="view-all">
查看全部 <i class="fas fa-chevron-right"></i>
</a>
</div>
<div class="apps-list">
{% if hot_apps %}
{% for app in hot_apps[:5] %}
<div class="app-item" onclick="handleAppClick(event, {{ app.id }});">
<div class="app-icon">
{% if 'http' in app.icon_path %}
<img data-src="{{ app.icon_path }}" alt="{{ app.name }}"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
loading="lazy"
cache="force-cache">
{% else %}
<img data-src="{{ url_for('static', filename='uploads/' + app.icon_path) }}"
alt="{{ app.name }}"
src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
loading="lazy"
cache="force-cache">
{% endif %}
</div>
<div class="app-info">
<h3>{{ app.name }}</h3>
<p class="app-category">{{ app.category_name }}</p>
</div>
</div>
{% endfor %}
{% else %}
<div class="no-apps-message">暂无热门应用</div>
{% endif %}
</div>
</section>
</section>
</main>
<!-- 底部导航栏 -->
<footer>
{% include 'nav_bar.html' %}
</footer>
<style>
/* 修改网站标题样式 */
.site-header {
background: rgba(245, 245, 247, 0.6);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
padding: 8px 15px 3px 15px;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 0px solid rgba(0, 0, 0, 0.05);
}
[data-theme="dark"] .site-header {
background: rgba(26, 26, 26, 0.6);
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.site-title {
display: flex;
align-items: center;
gap: 6px;
}
.site-logo {
height: 40px;
width: auto;
margin-right: 5px;
display: none;
}
.light-mode-logo {
display: block;
}
[data-theme="dark"] .light-mode-logo {
display: none;
}
[data-theme="dark"] .dark-mode-logo {
display: block;
}
.site-header h1 {
font-size: 28px;
font-weight: 700;
color: #000;
margin: 0;
text-align: left;
padding: 0;
}
[data-theme="dark"] .site-header h1 {
color: #fff;
}
.explore-container {
padding: 15px;
margin-bottom: 20px;
margin-top: 60px;
width: 100%;
max-width: 800px;
margin-left: auto;
margin-right: auto;
}
.explore-grid {
display: grid;
grid-template-columns: repeat(2, 370px);
grid-template-rows: repeat(2, auto);
gap: 15px;
justify-content: center;
}
.explore-item {
background: white;
border-radius: 24px;
overflow: hidden;
transition: transform 0.3s ease;
position: relative;
width: 370px;
line-height: 0;
box-shadow: none;
}
.explore-item:hover {
transform: translateY(-2px);
box-shadow: none;
}
.explore-item img {
width: 100%;
height: auto;
object-fit: cover;
transition: transform 0.2s ease;
transform: scale(1); /* 明确设置为原始大小 */
}
.explore-item:hover img {
transform: scale(1); /* 悬停时保持原始大小 */
}
/* 暗色模式适配 */
[data-theme="dark"] .explore-item {
background: #242424;
}
[data-theme="dark"] .explore-info {
background: rgba(36, 36, 36, 0.9);
}
[data-theme="dark"] .explore-info h3 {
color: #fff;
}
[data-theme="dark"] .explore-info p {
color: #999;
}
/* 响应式调整 */
@media (max-width: 1024px) {
.explore-grid {
grid-template-columns: repeat(2, 370px);
}
}
@media (max-width: 800px) {
.explore-grid {
grid-template-columns: 370px;
gap: 10px;
}
.explore-container {
padding: 10px;
margin-top: 55px;
}
.hot-apps-section {
margin: 0 auto;
}
}
/* 充电按钮样式 */
.button {
--h-button: 42px; /* 减小高度 */
--w-button: 88px; /* 减小宽度 */
--round: 0.75rem;
cursor: pointer;
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
overflow: hidden;
transition: all 0.25s ease;
background: radial-gradient(
65.28% 65.28% at 50% 100%,
rgba(223, 113, 255, 0.8) 0%,
rgba(223, 113, 255, 0) 100%
),
linear-gradient(0deg, #7a5af8, #7a5af8);
border-radius: var(--round);
border: none;
outline: none;
padding: 10px 16px; /* 减小内边距 */
}
.button::before {
--space: 1px;
background: linear-gradient(
177.95deg,
rgba(255, 255, 255, 0.19) 0%,
rgba(255, 255, 255, 0) 100%
);
}
.button::after {
--space: 2px;
background: radial-gradient(
65.28% 65.28% at 50% 100%,
rgba(223, 113, 255, 0.8) 0%,
rgba(223, 113, 255, 0) 100%
),
linear-gradient(0deg, #7a5af8, #7a5af8);
}
.button:active {
transform: scale(0.95);
}
.fold {
z-index: 1;
position: absolute;
top: 0;
right: 0;
height: 0.8rem; /* 减小折角大小 */
width: 0.8rem;
display: inline-block;
transition: all 0.5s ease-in-out;
background: radial-gradient(
100% 75% at 55%,
rgba(223, 113, 255, 0.8) 0%,
rgba(223, 113, 255, 0) 100%
);
box-shadow: 0 0 3px black;
border-bottom-left-radius: 0.5rem;
border-top-right-radius: var(--round);
}
.fold::after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 150%;
height: 150%;
transform: rotate(45deg) translateX(0%) translateY(-18px);
background-color: #e8e8e8;
pointer-events: none;
}
.button:hover .fold {
margin-top: -1rem;
margin-right: -1rem;
}
.points_wrapper {
overflow: hidden;
width: 100%;
height: 100%;
pointer-events: none;
position: absolute;
z-index: 1;
}
.points_wrapper .point {
bottom: -10px;
position: absolute;
animation: floating-points infinite ease-in-out;
pointer-events: none;
width: 2px;
height: 2px;
background-color: #fff;
border-radius: 9999px;
}
@keyframes floating-points {
0% {
transform: translateY(0);
}
85% {
opacity: 0;
}
100% {
transform: translateY(-55px);
opacity: 0;
}
}
/* 设置每个点的位置和动画 */
.points_wrapper .point:nth-child(1) { left: 10%; opacity: 1; animation-duration: 2.35s; animation-delay: 0.2s; }
.points_wrapper .point:nth-child(2) { left: 30%; opacity: 0.7; animation-duration: 2.5s; animation-delay: 0.5s; }
.points_wrapper .point:nth-child(3) { left: 25%; opacity: 0.8; animation-duration: 2.2s; animation-delay: 0.1s; }
.points_wrapper .point:nth-child(4) { left: 44%; opacity: 0.6; animation-duration: 2.05s; }
.points_wrapper .point:nth-child(5) { left: 50%; opacity: 1; animation-duration: 1.9s; }
.points_wrapper .point:nth-child(6) { left: 75%; opacity: 0.5; animation-duration: 1.5s; animation-delay: 1.5s; }
.points_wrapper .point:nth-child(7) { left: 88%; opacity: 0.9; animation-duration: 2.2s; animation-delay: 0.2s; }
.points_wrapper .point:nth-child(8) { left: 58%; opacity: 0.8; animation-duration: 2.25s; animation-delay: 0.2s; }
.points_wrapper .point:nth-child(9) { left: 98%; opacity: 0.6; animation-duration: 2.6s; animation-delay: 0.1s; }
.points_wrapper .point:nth-child(10) { left: 65%; opacity: 1; animation-duration: 2.5s; animation-delay: 0.2s; }
.inner {
z-index: 2;
font-size: 14px; /* 减小文字大小 */
gap: 4px; /* 减小图标和文字的间距 */
position: relative;
width: 100%;
color: white;
display: inline-flex;
align-items: center;
justify-content: center;
transition: color 0.2s ease-in-out;
}
.inner svg.icon {
width: 16px; /* 减小图标大小 */
height: 16px;
transition: fill 0.1s linear;
}
.button:focus svg.icon {
fill: white;
}
.button:hover svg.icon {
fill: transparent;
animation:
dasharray 1s linear forwards,
filled 0.1s linear forwards 0.95s;
}
@keyframes dasharray {
from {
stroke-dasharray: 0 0 0 0;
}
to {
stroke-dasharray: 68 68 0 0;
}
}
@keyframes filled {
to {
fill: white;
}
}
/* 修改充电按钮的样式,增加右侧间距 */
.donate-new-button {
margin-right: 15px; /* 增加右侧间距 */
}
/* 暗色模式适配 */
[data-theme="dark"] .fold::after {
background-color: #333;
}
/* 移动端适配 */
@media (max-width: 768px) {
.button {
--h-button: 36px;
--w-button: 80px;
padding: 8px 14px;
}
.inner {
font-size: 13px;
}
.inner svg.icon {
width: 14px;
height: 14px;
}
.fold {
height: 0.7rem;
width: 0.7rem;
}
}
/* 弹窗样式 */
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
display: none;
justify-content: center;
align-items: center;
z-index: 9999;
}
.modal.show {
opacity: 1;
visibility: visible;
transition: opacity 0.3s ease, visibility 0.3s ease;
}
.modal.hide {
opacity: 0;
visibility: hidden;
transition: opacity 0.3s ease, visibility 0.3s ease;
}
.modal-content {
background: white;
border-radius: 12px;
padding: 0;
width: 90%;
max-width: 320px;
position: relative;
animation: modalShow 0.3s ease;
}
.modal-header {
padding: 15px 20px;
border-bottom: 1px solid #eee;
position: relative;
}
.modal-header h3 {
margin: 0;
font-size: 18px;
text-align: center;
color: #333;
}
.modal-body {
padding: 20px;
text-align: center;
}
.close {
position: absolute;
right: 15px;
top: 12px;
font-size: 24px;
color: #999;
cursor: pointer;
line-height: 1;
}
.qr-code {
width: 200px;
height: 200px;
margin: 0px auto;
display: block;
border-radius: 8px;
}
.group-number-container {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
margin: 15px 0;
}
.group-number {
margin: 0;
color: #666;
font-size: 16px;
}
.group-tip {
margin: 15px 0;
color: #666;
font-size: 16px;
}
.join-btn {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 20px;
border-radius: 20px;
text-decoration: none;
font-size: 15px;
transition: all 0.3s ease;
border: none;
cursor: pointer;
}
.qq-join-btn {
background: #12B7F5;
color: white;
}
.wechat-join-btn {
background: #07C160;
color: white;
}
.join-btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(18, 183, 245, 0.2);
}
/* 暗色模式适配 */
[data-theme="dark"] .modal-content {
background-color: #242424;
}
[data-theme="dark"] .modal-header {
border-color: #333;
}
[data-theme="dark"] .modal-header h3,
[data-theme="dark"] .group-number,
[data-theme="dark"] .group-tip {
color: #fff;
}
@keyframes modalShow {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 复制按钮样式 */
.copy-btn {
background: none;
border: none;
color: #666;
cursor: pointer;
padding: 4px 8px;
font-size: 16px;
border-radius: 4px;
transition: all 0.3s ease;
}
.copy-btn:hover {
background: #f5f5f5;
color: #333;
}
/* 复制成功提示样式 */
.copy-notification {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 10px 20px;
border-radius: 20px;
font-size: 14px;
opacity: 0;
visibility: hidden;
transition: all 0.3s ease;
z-index: 10000;
}
.copy-notification.show {
opacity: 1;
visibility: visible;
}
/* 暗色模式样式 */
[data-theme="dark"] .copy-btn {
color: #999;
}
[data-theme="dark"] .copy-btn:hover {
background: #333;
color: #fff;
}
/* 充电弹窗样式 */
.donate-modal {
max-width: 360px;
background: linear-gradient(145deg, #ffffff, #f5f5f7);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
}
.donate-modal .modal-header {
background: linear-gradient(135deg, #7a5af8, #01b4ff);
padding: 15px 20px;
border-radius: 12px 12px 0 0;
position: relative;
}
.donate-modal .modal-header h3 {
color: white;
margin: 0;
text-align: center;
font-size: 18px;
font-weight: 600;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.donate-modal .close {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
color: white;
font-size: 24px;
opacity: 0.8;
cursor: pointer;
transition: all 0.3s ease;
}
.donate-modal .close:hover {
opacity: 1;
transform: translateY(-50%) scale(1.1);
}
.donate-modal .modal-body {
padding: 20px;
}
.donate-container {
text-align: center;
}
.donate-text {
color: #333;
font-size: 16px;
margin: 0 0 20px 0;
line-height: 1.5;
}
.donate-qr {
width: 200px;
height: 200px;
margin: 0 auto 20px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
}
.donate-qr:hover {
transform: scale(1.02);
}
.donate-note {
color: #666;
font-size: 14px;
margin: 0;
line-height: 1.4;
padding: 10px 15px;
background: rgba(0, 0, 0, 0.03);
border-radius: 8px;
display: inline-block;
}
/* 添加动画效果 */
@keyframes donateModalShow {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.donate-modal {
animation: donateModalShow 0.3s ease forwards;
}
/* 暗色模式适配 */
[data-theme="dark"] .donate-modal {
background: linear-gradient(145deg, #1c1c1e, #2c2c2e);
border-color: rgba(255, 255, 255, 0.1);
}
[data-theme="dark"] .donate-text {
color: #fff;
}
[data-theme="dark"] .donate-note {
color: #999;
background: rgba(255, 255, 255, 0.05);
}
[data-theme="dark"] .donate-qr {
filter: brightness(0.9);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
/* 移动端适配 */
@media (max-width: 768px) {
.donate-modal {
width: 90%;
max-width: 320px;
}
.donate-text {
font-size: 15px;
margin: 0 0 15px 0;
}
.donate-qr {
width: 180px;
height: 180px;
margin: 0 auto 15px;
}
.donate-note {
font-size: 13px;
padding: 8px 12px;
}
}
/* 确保在 Safari 上也有毛玻璃效果 */
@supports not (backdrop-filter: blur(10px)) {
.site-header {
background: rgba(255, 255, 255, 0.85);
}
[data-theme="dark"] .site-header {
background: rgba(26, 26, 26, 0.85);
}
}
/* 固定尺寸的探索项 */
.explore-item.fixed-size {
width: 370px;
height: 370px;
position: relative;
}
.explore-item.fixed-size img {
width: 100%;
height: 100%;
object-fit: cover;
}
/* 移动端适配固定尺寸 */
@media (max-width: 768px) {
.explore-item.fixed-size {
width: 370px;
height: 370px;
margin: 0 auto; /* 居中显示 */
}
}
/* 今日上新展示条样式 */
.new-apps-bar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
background: transparent;
padding: 5px 0;
border-bottom-left-radius: 24px;
border-bottom-right-radius: 24px;
height: 100px;
}
.new-apps-bar {
backdrop-filter: none;
-webkit-backdrop-filter: none;
}
[data-theme="dark"] .new-apps-bar {
background: transparent;
}
.new-apps-bar .apps-scroll {
overflow-x: auto;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
-ms-overflow-style: none;
height: 100%;
width: 100%;
display: flex;
align-items: center;
}
.new-apps-bar .apps-row {
display: flex;
gap: 2px;
width: auto;
height: 85px;
align-items: center;
}
.new-apps-bar .app-card {
flex: 0 0 auto;
width: 64px;
height: 85px;
padding: 4px;
background: transparent;
cursor: pointer;
transition: transform 0.2s ease;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.new-apps-bar .app-icon {
width: 48px;
height: 48px;
margin: 0 auto 4px;
border-radius: 12px;
overflow: hidden;
background: white;
display: flex;
align-items: center;
justify-content: center;
}
.new-apps-bar .app-icon img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 12px;
}
.new-apps-bar .app-info {
width: 100%;
text-align: center;
}
.new-apps-bar .app-info h3 {
font-size: 11px;
margin: 0;
color: #333;
text-shadow: none;
text-align: center;
line-height: 1.2;
height: auto;
max-height: 2.4em;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
padding: 0 2px;
}
.new-apps-bar .no-apps-message {
width: 100%;
text-align: center;
padding: 15px;
color: #333;
font-size: 14px;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
[data-theme="dark"] .new-apps-bar {
background: transparent;
}
[data-theme="dark"] .new-apps-bar .app-info h3 {
color: #000000;
}
[data-theme="dark"] .new-apps-bar .app-icon {
background: #242424;
}
[data-theme="dark"] .new-apps-bar .no-apps-message {
color: #ffffff;
}
/* 修改热门应用区域样式 */
.hot-apps-section {
background: white;
border-radius: 24px;
padding: 15px;
height: 370px;
overflow-y: auto; /* 恢复滚动功能 */
width: 370px;
}
/* 美化滚动条 */
.hot-apps-section::-webkit-scrollbar {
width: 4px;
}
.hot-apps-section::-webkit-scrollbar-track {
background: transparent;
}
.hot-apps-section::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, 0.1);
border-radius: 2px;
}
/* 修改应用列表样式 */
.apps-list {
display: flex;
flex-direction: column;
}
/* 修改应用项样式,添加分隔线 */
.app-item {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 8px;
border-bottom: 1px solid #f0f0f0; /* 添加分隔线 */
transition: background-color 0.3s ease;
cursor: pointer;
}
.app-item:last-child {
border-bottom: none; /* 最后一项不显示分隔线 */
}
/* 暗色模式适配 */
[data-theme="dark"] .hot-apps-section::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.1);
}
[data-theme="dark"] .app-item {
border-bottom-color: rgba(255, 255, 255, 0.05); /* 暗色模式分隔线颜色 */
}
/* 移动端适配 */
@media (max-width: 768px) {
.hot-apps-section {
height: auto;
width: 370px;
margin: 10px auto;
}
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.section-title {
display: flex;
align-items: center;
gap: 8px;
}
.section-title i {
color: #ff3b30;
font-size: 20px;
}
.section-title h2 {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #1a1a1a;
}
.view-all {
color: #007AFF;
text-decoration: none;
font-size: 15px;
font-weight: 500;
display: flex;
align-items: center;
gap: 4px;
}
.view-all i {
font-size: 12px;
}
.apps-list {
display: flex;
flex-direction: column;
gap: 1px;
}
.app-item {
display: flex;
align-items: center;
gap: 12px;
padding: 8px;
border-radius: 12px;
transition: background-color 0.3s ease;
cursor: pointer;
}
.app-item:hover {
background-color: #f5f5f5;
}
.app-rank {
width: 24px;
font-size: 17px;
font-weight: 600;
color: #1a1a1a;
opacity: 0.5;
}
.app-icon {
width: 56px;
height: 56px;
margin-right: 12px;
border-radius: 12px;
overflow: hidden;
background: #f5f5f5;
flex-shrink: 0; /* 防止图标缩小 */
}
.app-icon img {
width: 100%;
height: 100%;
object-fit: cover;
}
.app-info {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
justify-content: center; /* 垂直居中 */
padding-right: 5px; /* 右侧添加一些间距 */
}
.app-info h3 {
margin: 0 0 4px;
font-size: 17px;
font-weight: 500;
color: #1a1a1a;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
text-align: left;
padding: 0; /* 移除可能的内边距 */
align-items: flex-start; /* 内容左对齐 */
display: flex;
justify-content: flex-start;
}
.app-category {
margin: 0;
font-size: 13px;
color: #666;
width: 100%;
text-align: left;
padding: 0; /* 移除可能的内边距 */
}
.download-btn {
padding: 6px 12px;
border-radius: 15px;
background: #f2f2f2;
display: flex;
align-items: center;
justify-content: center;
margin-left: 12px;
font-size: 13px;
color: #007AFF;
transition: all 0.2s ease;
}
.download-btn:hover {
background: #e5e5e5;
}
/* 暗色模式适配 */
[data-theme="dark"] .hot-apps-section {
background: #242424;
}
[data-theme="dark"] .section-title h2 {
color: #fff;
}
[data-theme="dark"] .app-rank {
color: #fff;
}
[data-theme="dark"] .app-info h3 {
color: #fff;
}
[data-theme="dark"] .app-category {
color: #999;
}
[data-theme="dark"] .app-item {
border-bottom-color: rgba(255,255,255,0.1);
}
[data-theme="dark"] .download-btn {
background: #2c2c2e;
color: #0A84FF;
}
[data-theme="dark"] .download-btn:hover {
background: #3c3c3e;
}
@media (max-width: 768px) {
.app-icon {
width: 48px;
height: 48px;
margin-right: 10px;
}
.download-btn {
padding: 4px 10px;
font-size: 12px;
}
}
/* 移动端适配 */
@media (max-width: 768px) {
.hot-apps-section {
height: auto; /* 移动端自适应高度 */
width: 370px;
margin: 10px auto;
}
}
/* 添加小屏幕的特殊处理 */
@media (max-width: 400px) {
.explore-item.fixed-size {
width: calc(100% - 20px);
margin: 0 10px;
}
.hot-apps-section {
width: calc(100% - 20px);
margin: 20px 10px;
}
}
/* 修改热门应用区域的暗色模式样式 */
[data-theme="dark"] .hot-apps-section {
background: #242424;
}
[data-theme="dark"] .section-title h2 {
color: #fff;
}
[data-theme="dark"] .app-info h3 {
color: #fff;
}
[data-theme="dark"] .app-category {
color: #999;
}
[data-theme="dark"] .app-item {
border-bottom-color: rgba(255, 255, 255, 0.05);
}
[data-theme="dark"] .app-item:hover {
background-color: rgba(255, 255, 255, 0.05);
}
[data-theme="dark"] .view-all {
color: #0A84FF;
}
[data-theme="dark"] .no-apps-message {
color: #ffffff;
}
[data-theme="dark"] .hot-apps-section::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.1);
}
/* 修改样式以适应5个应用的固定显示并使图标居中 */
.new-apps-bar {
width: 100%;
overflow: hidden;
padding: 10px;
}
.apps-row {
display: grid;
grid-template-columns: repeat(5, 1fr); /* 5列等宽布局 */
gap: 10px; /* 应用之间的间距 */
justify-items: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
}
.app-card {
width: 100%;
max-width: 80px; /* 限制最大宽度 */
display: flex;
flex-direction: column;
align-items: center; /* 内容居中 */
justify-content: center; /* 垂直居中 */
padding: 10px;
border-radius: 8px;
transition: all 0.3s ease;
}
.app-card .app-icon {
width: 60px; /* 固定图标大小 */
height: 60px;
margin-bottom: 8px; /* 图标和文字之间的间距 */
}
.app-card .app-icon img {
width: 100%;
height: 100%;
border-radius: 12px;
object-fit: cover;
}
.app-card .app-info {
width: 100%;
text-align: center; /* 文字居中 */
}
.app-card .app-info h3 {
font-size: 12px;
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #333;
}
/* 响应式布局 */
@media (max-width: 768px) {
.apps-row {
grid-template-columns: repeat(3, 1fr); /* 在小屏幕上显示3列 */
}
}
@media (max-width: 480px) {
.apps-row {
grid-template-columns: repeat(2, 1fr); /* 在更小的屏幕上显示2列 */
}
}
/* 暗色模式适配 */
[data-theme="dark"] .app-card .app-info h3 {
color: #fff;
}
/* 修改 apps-row 的样式,支持水平滚动 */
.new-apps-bar {
width: 100%;
overflow: hidden;
}
.apps-row {
display: flex; /* 改为 flex 布局 */
overflow-x: auto; /* 允许水平滚动 */
overflow-y: hidden; /* 隐藏垂直滚动条 */
scroll-behavior: smooth; /* 平滑滚动 */
-webkit-overflow-scrolling: touch; /* 在 iOS 上支持惯性滚动 */
scrollbar-width: none; /* Firefox 隐藏滚动条 */
-ms-overflow-style: none; /* IE 和 Edge 隐藏滚动条 */
}
/* 隐藏 Webkit 浏览器的滚动条 */
.apps-row::-webkit-scrollbar {
display: none;
}
.app-card {
flex: 0 0 auto; /* 防止 flex 项目被压缩 */
width: 60px; /* 固定宽度 */
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.app-card:last-child {
margin-right: 0; /* 最后一个卡片不需要右边距 */
}
.app-card .app-icon {
width: 50px;
height: 50px;
margin-bottom: 4px;
}
.app-card .app-icon img {
width: 100%;
height: 100%;
border-radius: 12px;
object-fit: cover;
}
.app-card .app-info {
width: 100%;
text-align: center;
}
.app-card .app-info h3 {
font-size: 12px;
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #333;
}
/* 暗色模式适配 */
[data-theme="dark"] .app-card .app-info h3 {
color: #fff;
}
/* 添加图片加载优化相关样式 */
.explore-item img {
will-change: transform; /* 提示浏览器图片将会变化 */
backface-visibility: hidden; /* 防止闪烁 */
transform: translateZ(0); /* 启用GPU加速 */
transition: opacity 0.3s ease; /* 平滑过渡效果 */
}
/* 添加图片加载占位样式 */
.explore-item img[data-src] {
opacity: 0;
}
.explore-item img:not([data-src]) {
opacity: 1;
}
/* 心愿单通知弹窗样式 */
.wishlist-announcement {
position: fixed;
top: 60px;
left: 50%;
transform: translateX(-50%);
width: 90%;
max-width: 400px;
background: linear-gradient(135deg, #4F46E5, #7C3AED);
border-radius: 12px;
padding: 12px 12px 0 12px;
box-shadow: 0 8px 20px rgba(124, 58, 237, 0.25);
z-index: 1000;
overflow: hidden;
animation: slideDown 0.5s ease-out;
touch-action: pan-x; /* 允许水平滑动 */
user-select: none; /* 防止文本选择 */
transition: transform 0.3s ease; /* 添加平滑过渡 */
}
/* 添加滑动时的动画效果 */
.wishlist-announcement.swiping {
transition: transform 0.1s ease;
}
/* 添加滑动完成后的动画效果 */
.wishlist-announcement.swipe-out {
transform: translate(calc(-50% - 150%), 0);
opacity: 0;
}
.announcement-content {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
}
.announcement-text {
color: white;
font-size: 16px;
font-weight: 600;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.goto-btn {
background: rgba(255, 255, 255, 0.2);
color: white;
border: 1px solid rgba(255, 255, 255, 0.3);
padding: 6px 14px;
border-radius: 8px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s ease;
font-weight: 500;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
.goto-btn:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-1px);
border-color: rgba(255, 255, 255, 0.5);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.close-btn {
background: none;
border: none;
color: white;
font-size: 20px;
cursor: pointer;
padding: 0 6px;
opacity: 0.8;
transition: opacity 0.3s ease;
}
.close-btn:hover {
opacity: 1;
}
.countdown-bar {
height: 3px;
background: rgba(255, 255, 255, 0.2);
border-radius: 0;
overflow: hidden;
position: relative;
margin: 0 -12px;
width: calc(100% + 24px);
}
.countdown-bar::after {
content: '';
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: linear-gradient(90deg, rgba(255,255,255,0.8), rgba(255,255,255,1));
animation: countdown 5s linear forwards;
}
@keyframes slideDown {
from {
transform: translate(-50%, -100%);
opacity: 0;
}
to {
transform: translate(-50%, 0);
opacity: 1;
}
}
@keyframes countdown {
from {
width: 100%;
}
to {
width: 0;
}
}
/* 暗色模式适配 */
[data-theme="dark"] .wishlist-announcement {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
/* 抖音关注按钮样式 */
.douyin-follow-container {
display: flex;
justify-content: center;
margin-bottom: 15px;
}
.douyin-follow-btn {
display: inline-flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #FE2C55, #FF6B6B); /* 使用渐变色 */
color: white;
padding: 10px 20px;
border-radius: 25px;
text-decoration: none;
font-weight: bold;
transition: all 0.3s ease;
box-shadow: 0 6px 15px rgba(254, 44, 85, 0.3); /* 更柔和的阴影 */
position: relative;
overflow: hidden; /* 为了后续的光效 */
}
.douyin-follow-btn::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(
45deg,
rgba(255,255,255,0.1) 0%,
rgba(255,255,255,0.3) 50%,
rgba(255,255,255,0) 100%
);
transform: rotate(-45deg);
opacity: 0;
transition: opacity 0.3s ease;
}
.douyin-follow-btn:hover::before {
opacity: 1;
}
.douyin-follow-btn:hover {
transform: scale(1.05);
box-shadow: 0 8px 20px rgba(254, 44, 85, 0.4);
}
.douyin-icon {
width: 24px;
height: 24px;
margin-right: 8px;
filter: drop-shadow(0 2px 2px rgba(0,0,0,0.2)); /* 添加轻微阴影 */
}
/* 暗色模式适配 */
[data-theme="dark"] .douyin-follow-btn {
background: linear-gradient(135deg, #FF4757, #FF6B6B);
color: white;
opacity: 0.9;
}
[data-theme="dark"] .douyin-follow-btn:hover {
opacity: 1;
}
/* 响应式调整 */
@media (max-width: 768px) {
.douyin-follow-btn {
padding: 8px 16px;
font-size: 14px;
}
.douyin-icon {
width: 20px;
height: 20px;
margin-right: 6px;
}
}
</style>
<script>
// 复制群号功能
function copyGroupNumber() {
// 从群号文本中提取纯数字
const groupNumber = document.querySelector('.group-number').textContent.match(/\d+/)[0];
// 使用 Clipboard API 复制文本
navigator.clipboard.writeText(groupNumber).then(() => {
// 显示复制成功提示
const notification = document.getElementById('copy-notification');
notification.classList.add('show');
// 1.5秒后藏提示
setTimeout(() => {
notification.classList.remove('show');
}, 1500);
}).catch(err => {
console.error('复制失败:', err);
// 使用备用方案
const textarea = document.createElement('textarea');
textarea.value = groupNumber;
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
// 显示复制成功提示
const notification = document.getElementById('copy-notification');
notification.classList.add('show');
setTimeout(() => {
notification.classList.remove('show');
}, 1500);
} catch (err) {
console.error('备用复制方案失败:', err);
}
document.body.removeChild(textarea);
});
}
function showDonateModal() {
const modal = document.getElementById('donate-modal');
if (modal) {
modal.style.display = 'flex';
modal.classList.add('show');
modal.classList.remove('hide');
document.body.style.overflow = 'hidden';
}
}
function closeDonateModal() {
const modal = document.getElementById('donate-modal');
if (modal) {
modal.classList.add('hide');
modal.classList.remove('show');
setTimeout(() => {
modal.style.display = 'none';
}, 300);
document.body.style.overflow = '';
}
}
// 点击弹窗外部关闭
window.onclick = function(event) {
const modal = document.getElementById('donate-modal');
if (event.target === modal) {
closeDonateModal();
}
}
function showQQModal() {
const modal = document.getElementById('qq-modal');
if (modal) {
modal.style.display = 'flex';
modal.classList.add('show');
modal.classList.remove('hide');
document.body.style.overflow = 'hidden';
}
}
function closeQQModal() {
const modal = document.getElementById('qq-modal');
if (modal) {
modal.classList.add('hide');
modal.classList.remove('show');
setTimeout(() => {
modal.style.display = 'none';
}, 300);
document.body.style.overflow = '';
}
}
function showWeChatModal() {
const modal = document.getElementById('wechat-modal');
if (modal) {
modal.style.display = 'flex';
modal.classList.add('show');
modal.classList.remove('hide');
document.body.style.overflow = 'hidden';
}
}
function closeWeChatModal() {
const modal = document.getElementById('wechat-modal');
if (modal) {
modal.classList.add('hide');
modal.classList.remove('show');
setTimeout(() => {
modal.style.display = 'none';
}, 300);
document.body.style.overflow = '';
}
}
// 添加保存和恢复滚动位置的功能
window.addEventListener('beforeunload', () => {
const appsScroll = document.querySelector('.new-apps-bar .apps-scroll');
if (appsScroll) {
sessionStorage.setItem('appsScrollPosition', appsScroll.scrollLeft);
}
});
document.addEventListener('DOMContentLoaded', () => {
if (document.referrer.includes('/app/')) {
const appsScroll = document.querySelector('.new-apps-bar .apps-scroll');
const scrollPosition = sessionStorage.getItem('appsScrollPosition');
if (appsScroll && scrollPosition) {
appsScroll.scrollLeft = parseInt(scrollPosition);
}
sessionStorage.removeItem('appsScrollPosition');
}
});
// 修改图片加载逻辑
document.addEventListener('DOMContentLoaded', function() {
// 创建一个 Set 来跟踪已加载的图片
const loadedImages = new Set(JSON.parse(sessionStorage.getItem('loadedImages') || '[]'));
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
if (img.dataset.src) {
const imageUrl = img.dataset.src;
// 如果图片已经加载过,直接使用缓存
if (loadedImages.has(imageUrl)) {
img.src = imageUrl;
img.removeAttribute('data-src');
observer.unobserve(img);
return;
}
// 加载新图片
img.src = imageUrl;
img.onload = () => {
loadedImages.add(imageUrl);
sessionStorage.setItem('loadedImages', JSON.stringify([...loadedImages]));
img.removeAttribute('data-src');
};
observer.unobserve(img);
}
}
});
}, {
rootMargin: '50px 0px',
threshold: 0.01
});
// 为所有带有 data-src 的图片添加观察器
document.querySelectorAll('img[data-src]').forEach(img => {
// 如果图片已经加载过,直接显示
if (loadedImages.has(img.dataset.src)) {
img.src = img.dataset.src;
img.removeAttribute('data-src');
} else {
imageObserver.observe(img);
}
});
});
// 修改页面显示事件处理
window.addEventListener('pageshow', function(event) {
// 从缓存加载页面时的处理
if (event.persisted) {
const loadedImages = new Set(JSON.parse(sessionStorage.getItem('loadedImages') || '[]'));
document.querySelectorAll('img[data-src]').forEach(img => {
if (loadedImages.has(img.dataset.src)) {
img.src = img.dataset.src;
img.removeAttribute('data-src');
}
});
}
});
// 在页面离开时保存加载状态
window.addEventListener('beforeunload', function() {
// 获取所有已加载图片的URL
const loadedImages = new Set();
document.querySelectorAll('img:not([data-src])').forEach(img => {
if (img.src && !img.src.startsWith('data:')) {
loadedImages.add(img.src);
}
});
sessionStorage.setItem('loadedImages', JSON.stringify([...loadedImages]));
});
// 阻止事件冒泡的点击处理函数
function handleAppClick(event, appId) {
event.stopPropagation();
window.location.href = '/app/' + appId;
}
// 在点击进入new_apps页面时保存来源
document.querySelector('.explore-item').addEventListener('click', function() {
sessionStorage.setItem('fromExplore', 'true');
});
// 页面加载时检查是否需要保存滚动位置
window.addEventListener('beforeunload', () => {
// 只有当进入new_apps页面时才保存位置
if (window.location.pathname === '/explore') {
sessionStorage.setItem('exploreScrollPosition', window.scrollY);
}
});
// 页面加载完成后检查是否从new_apps返回
document.addEventListener('DOMContentLoaded', () => {
if (document.referrer.includes('/new_apps') && sessionStorage.getItem('fromExplore')) {
// 恢复滚动位置
const scrollPosition = sessionStorage.getItem('exploreScrollPosition');
if (scrollPosition) {
window.scrollTo(0, parseInt(scrollPosition));
}
// 清除标记
sessionStorage.removeItem('fromExplore');
sessionStorage.removeItem('exploreScrollPosition');
}
});
// 添加页面缓存控制
window.addEventListener('pageshow', function(event) {
// 如果是从缓存加载的页面
if (event.persisted) {
// 恢复已加载的图片
document.querySelectorAll('img[data-src]').forEach(img => {
const cachedSrc = localStorage.getItem(img.dataset.src);
if (cachedSrc) {
img.src = cachedSrc;
img.removeAttribute('data-src');
}
});
}
});
// 心愿单通知弹窗相关函数
function closeAnnouncement() {
const announcement = document.getElementById('wishlist-announcement');
announcement.style.animation = 'slideUp 0.5s ease-out forwards';
setTimeout(() => {
announcement.remove();
}, 500);
}
// 自动关闭倒计时
setTimeout(closeAnnouncement, 5000);
// 添加向上滑动的动画
const style = document.createElement('style');
style.textContent = `
@keyframes slideUp {
from {
transform: translate(-50%, 0);
opacity: 1;
}
to {
transform: translate(-50%, -100%);
opacity: 0;
}
}
`;
document.head.appendChild(style);
// 添加滑动删除功能
let touchStartX = 0;
let touchEndX = 0;
let currentTranslateX = 0;
let isDragging = false;
document.addEventListener('DOMContentLoaded', () => {
const announcement = document.getElementById('wishlist-announcement');
if (!announcement) return;
// 触摸开始
announcement.addEventListener('touchstart', (e) => {
touchStartX = e.touches[0].clientX;
isDragging = true;
announcement.classList.add('swiping');
});
// 触摸移动
announcement.addEventListener('touchmove', (e) => {
if (!isDragging) return;
touchEndX = e.touches[0].clientX;
const diffX = touchEndX - touchStartX;
// 只允许左滑
if (diffX > 0) {
currentTranslateX = 0;
} else {
currentTranslateX = diffX;
}
// 应用变换
announcement.style.transform = `translate(calc(-50% + ${currentTranslateX}px), 0)`;
});
// 触摸结束
announcement.addEventListener('touchend', () => {
isDragging = false;
announcement.classList.remove('swiping');
// 如果滑动距离超过阈值,则关闭通知
if (currentTranslateX < -100) {
announcement.classList.add('swipe-out');
setTimeout(() => {
announcement.remove();
}, 300);
} else {
// 否则回弹
announcement.style.transform = 'translateX(-50%)';
}
// 重置状态
currentTranslateX = 0;
touchStartX = 0;
touchEndX = 0;
});
// 鼠标事件支持
announcement.addEventListener('mousedown', (e) => {
touchStartX = e.clientX;
isDragging = true;
announcement.classList.add('swiping');
});
announcement.addEventListener('mousemove', (e) => {
if (!isDragging) return;
touchEndX = e.clientX;
const diffX = touchEndX - touchStartX;
if (diffX > 0) {
currentTranslateX = 0;
} else {
currentTranslateX = diffX;
}
announcement.style.transform = `translate(calc(-50% + ${currentTranslateX}px), 0)`;
});
announcement.addEventListener('mouseup', () => {
if (!isDragging) return;
isDragging = false;
announcement.classList.remove('swiping');
if (currentTranslateX < -100) {
announcement.classList.add('swipe-out');
setTimeout(() => {
announcement.remove();
}, 300);
} else {
announcement.style.transform = 'translateX(-50%)';
}
currentTranslateX = 0;
touchStartX = 0;
touchEndX = 0;
});
// 处理鼠标离开窗口的情况
announcement.addEventListener('mouseleave', () => {
if (isDragging) {
isDragging = false;
announcement.classList.remove('swiping');
announcement.style.transform = 'translateX(-50%)';
currentTranslateX = 0;
touchStartX = 0;
touchEndX = 0;
}
});
});
// Add this to the existing script section
document.addEventListener('DOMContentLoaded', function() {
// Theme-based image switching
function updateThemeImages() {
const isDarkMode = document.documentElement.getAttribute('data-theme') === 'dark';
document.querySelectorAll('img[data-light-src][data-dark-src]').forEach(img => {
const lightSrc = img.getAttribute('data-light-src');
const darkSrc = img.getAttribute('data-dark-src');
// Remove data-src to prevent default lazy loading
img.removeAttribute('data-src');
if (isDarkMode) {
img.src = darkSrc;
} else {
img.src = lightSrc;
}
});
}
// Call on initial load to set correct image based on current theme
updateThemeImages();
// Add listener for theme changes
const observer = new MutationObserver(updateThemeImages);
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['data-theme']
});
});
</script>
{% endblock %}