Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions templates/assets/css/pageforge-reading-progress.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* 进度条容器 */
#reading-progress-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 4px;
background-color: rgba(229, 231, 235, 0.3); /* 浅灰色背景 */
z-index: 9999;
}

/* 进度条 */
#reading-progress-bar {
height: 100%;
background: linear-gradient(to right, #3b82f6, #60a5fa);
width: 0%;
transition: width 0.1s ease;
}

/* 进度指示器 */
#reading-progress-indicator {
position: fixed;
right: 5rem;
bottom: 1rem;
background-color: rgba(31, 41, 55, 0.8);
color: white;
padding: 0.5rem 0.75rem;
border-radius: 9999px;
font-size: 0.875rem;
font-weight: 500;
opacity: 0.8;
transition: opacity 0.2s ease;
cursor: pointer;
z-index: 9999;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}

#reading-progress-indicator:hover {
opacity: 1;
}

#reading-progress-indicator.hidden {
opacity: 0;
pointer-events: none;
}

/* 暗黑模式下的样式 */
.dark #reading-progress-container {
background-color: rgba(55, 65, 81, 0.3);
}

.dark #reading-progress-bar {
background: linear-gradient(to right, #60a5fa, #93c5fd);
}

.dark #reading-progress-indicator {
background-color: rgba(55, 65, 81, 0.9);
}

/* 在移动设备上调整样式 */
@media (max-width: 768px) {
#reading-progress-bar {
height: 5px;
}

#reading-progress-indicator {
font-size: 0.75rem;
padding: 0.35rem 0.6rem;
}
}
111 changes: 111 additions & 0 deletions templates/assets/js/pageforge-reading-progress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* 初始化高级阅读进度条
* 包含顶部进度条和悬浮百分比显示
*/
function initAdvancedReadingProgress() {
// 创建容器元素
const progressContainer = document.createElement('div');
progressContainer.id = 'reading-progress-container';

// 创建进度条元素
const progressBar = document.createElement('div');
progressBar.id = 'reading-progress-bar';

// 创建百分比显示元素
const progressIndicator = document.createElement('div');
progressIndicator.id = 'reading-progress-indicator';
progressIndicator.className = 'fixed right-4 bottom-4 bg-gray-800 dark:bg-gray-700 text-white px-3 py-2 rounded-full text-sm font-medium opacity-80 hover:opacity-100 transition-opacity';
progressIndicator.innerHTML = '0%';

// 添加元素到页面
progressContainer.appendChild(progressBar);
document.body.appendChild(progressContainer);
document.body.appendChild(progressIndicator);

// 获取内容元素 - 假设文章内容在 .article-content 类的元素中
const contentElement = document.querySelector('.article-content') || document.querySelector('main') || document.body;

// 存储原始标题
const originalTitle = document.title;

// 计算内容区域的位置和高度
const getContentHeight = () => {
const contentRect = contentElement.getBoundingClientRect();
const contentTop = contentRect.top + window.scrollY;
const contentHeight = contentRect.height;

// 考虑到页脚和其他元素的高度,我们通常只计算到页面底部前的一部分
const visibleContentHeight = contentHeight - window.innerHeight;

return {
start: contentTop,
height: visibleContentHeight
};
};

// 创建节流函数以减少更新频率
function throttle(callback, limit) {
let waiting = false;
return function () {
if (!waiting) {
callback.apply(this, arguments);
waiting = true;
setTimeout(function () {
waiting = false;
}, limit);
}
};
}

// 更新进度条和指示器
function updateProgress() {
const content = getContentHeight();
const scrolled = window.scrollY - content.start;

// 计算阅读进度百分比
let progressPercent = 0;
if (scrolled > 0) {
progressPercent = Math.min(100, Math.max(0, (scrolled / content.height) * 100));
}

// 舍入到整数用于显示
const displayPercent = Math.round(progressPercent);

// 更新进度条宽度
progressBar.style.width = `${progressPercent}%`;

// 更新百分比指示器
progressIndicator.textContent = `${displayPercent}%`;

// 根据进度显示或隐藏指示器
if (displayPercent > 0 && displayPercent < 100) {
progressIndicator.classList.remove('hidden');
}
else {
progressIndicator.classList.add('hidden');
}
}

// 使用节流函数减少更新频率,每100毫秒更新一次
const throttledUpdateProgress = throttle(updateProgress, 100);

// 添加事件监听器
window.addEventListener('scroll', throttledUpdateProgress, {passive: true});
window.addEventListener('resize', throttledUpdateProgress, {passive: true});

// 初始调用一次以设置初始状态
updateProgress();

// 点击百分比指示器时滚动到顶部
progressIndicator.addEventListener('click', function () {
window.scrollTo({top: 0, behavior: 'smooth'});
});
}

// 当页面加载完成后初始化进度条
if (document.readyState === 'complete') {
initAdvancedReadingProgress();
}
else {
window.addEventListener('load', initAdvancedReadingProgress);
}
4 changes: 2 additions & 2 deletions templates/components/issues.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ module.exports = function template(item) {
<a href="${item.href}"
target="_blank"
class="inline-flex items-center px-2.5 py-1.5 rounded-md bg-gray-100 hover:bg-gray-200 text-gray-900 dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-100 transition-colors duration-200 no-underline max-w-md">
<svg class="w-5 h-5 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<svg class="w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4"></path>
<path d="M9 18c-4.51 2-5-2-7-2"></path>
</svg>
<span class="flex-1">
<span class="font-semibold">${owner}/${repo}</span>
<span class="inline-flex items-center ml-1">
<span class="w-4 h-4 inline-flex items-center justify-center bg-gray-600 dark:bg-gray-400 rounded-full text-white text-xs mr-1">
<span class="w-3 h-3 inline-flex items-center justify-center bg-gray-600 dark:bg-gray-400 rounded-full text-white text-xs mr-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="12" height="12" fill="currentColor">
<path d="M8 9.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"></path>
<path fill-rule="evenodd" d="M8 0a8 8 0 100 16A8 8 0 008 0zM1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0z"></path>
Expand Down