// ========== 网站链接数据 (包含中英双语) ==========
const websitesData = [
{ category_zh: '我的作品', category_en: 'My Works', items: [
{ url: 'https://mooknote.iletter.top/#/',
linkText_zh: 'MookNote - 观影阅读笔记管理',
linkText_en: 'MookNote - Movie & Reading Note Manager',
desc_zh: '用于记录观影、阅读及笔记的个人知识管理应用。',
desc_en: 'Personal knowledge management app for movies, reading, and notes.',
img: './static/img/my_work/mooknote/banner.jpg'
}
]},
{ category_zh: '个人博客', category_en: 'Personal Blogs', items: [
{ url: 'https://www.ittoolman.top/',
linkText_zh: 'ittoolman - Github托管',
linkText_en: 'ittoolman - Github Page',
desc_zh: '基于 GitHub Pages 搭建的个人技术站点。',
desc_en: 'Personal tech site based on GitHub Pages.',
img: './static/img/my_work/ittoolman/banner.png'
},
{ url: 'https://blog.iletter.top/',
linkText_zh: 'iletter - typecho极简与高效并存',
linkText_en: 'iletter - typecho Minimalism and Efficiency',
desc_zh: '记录日常开发与生活点滴的 Typecho 博客。',
desc_en: 'A Typecho blog recording daily development and life.',
img: './static/img/my_work/blog_iletter/banner.png'
}
]},
{ category_zh: '私人在线应用', category_en: 'Personal Online Apps', items: [
{ img: './static/img/my_work/easyimage2/banner.png',
url: 'https://img.iletter.top/', linkText_zh: 'EsayImage2 - 私人图床工具', linkText_en: 'EsayImage2 - Image Uploader Tool', desc_zh: '稳定高效的图片上传与托管服务。', desc_en: 'Stable and efficient image hosting service.' },
{ url: 'https://gitea.iletter.top/', linkText_zh: 'Gitea - 私人git托管仓库', linkText_en: 'Gitea - Private Git Repository', desc_zh: '轻量级自托管 Git 代码管理平台。', desc_en: 'Lightweight self-hosted Git code management platform.' },
{ url: 'http://umami.iletter.top/', linkText_zh: 'Umami - 网站访问分析', linkText_en: 'Umami - Website visit analysis', desc_zh: '简洁、隐私友好的网站流量统计工具。', desc_en: 'Simple, privacy-friendly website analytics tool.' },
{ url: 'http://beszel.iletter.top/', linkText_zh: 'Beszel - 服务器监控', linkText_en: 'Beszel - Server Monitoring', desc_zh: '实时监控服务器资源占用情况。', desc_en: 'Real-time monitoring of server resource usage.' },
{ url: 'https://memos.iletter.top/', linkText_zh: 'Memos - 个人随想', linkText_en: 'Memos - Personal Thoughts', desc_zh: '碎片化知识管理与灵感记录空间。', desc_en: 'Fragmented knowledge management and inspiration space.' },
{ url: 'http://frp.iletter.top/', linkText_zh: 'FRP - 个人反向代理',
linkText_en: 'FRP - Personal Reverse Proxy', desc_zh: '用于内网穿透的高性能反向代理。',
desc_en: 'High-performance reverse proxy for intranet penetration.',
img: './static/img/my_work/frp_panel/banner.png'
},
{ img: './static/img/my_work/bitwarden/banner.png',
url: 'https://bitwarden.iletter.top/', linkText_zh: 'Bitwarden - 我的密码库', linkText_en: 'Bitwarden - My Password Library', desc_zh: '安全可靠的开源密码管理方案。', desc_en: 'Secure and reliable open-source password management solution.' },
{ url: 'http://docmost.iletter.top/', linkText_zh: 'Docmost - 在线笔记', linkText_en: 'Docmost - Online Notes', desc_zh: '支持协作的实时在线文档编辑平台。', desc_en: 'Real-time online document editing platform supporting collaboration.' },
{ img: './static/img/my_work/openlist/banner.png',
url: 'http://openlist.iletter.top/', linkText_zh: 'OpenList - 在线云盘合集', linkText_en: 'OpenList - Online Cloud Disk Collection', desc_zh: '聚合多种网盘服务的文件列表管理。', desc_en: 'File list management aggregating various cloud storage services.' }
]}
];
// ========== 渲染网站链接的函数 ==========
let currentViewMode = localStorage.getItem('website_view_mode') || 'card'; // 'list' or 'card'
function renderWebsites(websitesArray) {
const container = document.getElementById('dynamic-website-links');
if (!container) {
console.error("未找到网站链接容器 #dynamic-website-links");
return;
}
// 检查数组是否为空或未定义/未初始化
const arrayToRender = websitesArray || websitesData;
if (!arrayToRender || !Array.isArray(arrayToRender) || arrayToRender.length === 0) {
const currentLang = localStorage.getItem("preferred_language") || "zh";
let noDataMessage = currentLang === 'en' ? 'No website data available.' : '暂无网站数据';
container.innerHTML = `
${noDataMessage}
`;
return; // 提前结束函数
}
const currentLang = localStorage.getItem("preferred_language") || "zh";
// 清空容器并添加切换按钮
const toggleText = currentViewMode === 'list' ? '切换为卡片视图' : '切换为列表视图';
container.innerHTML = `
${toggleText}
`;
const contentArea = container.querySelector('#website-content-area');
if (currentViewMode === 'list') {
arrayToRender.forEach(categoryObj => {
const categoryName = currentLang === 'en' ? categoryObj.category_en : categoryObj.category_zh;
const heading = document.createElement('h3');
heading.textContent = categoryName;
contentArea.appendChild(heading);
const linksDiv = document.createElement('div');
linksDiv.className = 'category-links';
categoryObj.items.forEach(item => {
const linkElement = document.createElement('a');
linkElement.href = '#';
linkElement.textContent = currentLang === 'en' ? item.linkText_en : item.linkText_zh;
if (item.url === 'https://mooknote.iletter.top/#/') {
linkElement.onclick = (e) => {
e.preventDefault();
openMookNoteModal();
};
} else {
linkElement.onclick = (e) => {
e.preventDefault();
showCustomConfirm(`确定要打开网站吗?\n${item.url}`, () => {
window.open(item.url, '_blank');
});
};
}
linksDiv.appendChild(linkElement);
const space = document.createTextNode(' ');
linksDiv.appendChild(space);
});
contentArea.appendChild(linksDiv);
});
} else {
arrayToRender.forEach(categoryObj => {
const categoryName = currentLang === 'en' ? categoryObj.category_en : categoryObj.category_zh;
const heading = document.createElement('h3');
heading.textContent = categoryName;
contentArea.appendChild(heading);
const gridDiv = document.createElement('div');
gridDiv.className = 'website-card-grid';
categoryObj.items.forEach(item => {
const card = document.createElement('div');
card.className = 'website-card';
if (item.url === 'https://mooknote.iletter.top/#/') {
card.onclick = () => openMookNoteModal();
} else {
card.onclick = () => {
showCustomConfirm(`确定要打开网站吗?\n${item.url}`, () => {
window.open(item.url, '_blank');
});
};
}
const title = currentLang === 'en' ? item.linkText_en : item.linkText_zh;
const desc = currentLang === 'en' ? (item.desc_en || '') : (item.desc_zh || '');
const imgSrc = item.img;
const placeholderText = item.linkText_zh.split(' - ')[0];
const imgHtml = imgSrc
? ``
: `${placeholderText}
`;
card.innerHTML = `
${imgHtml}
`;
gridDiv.appendChild(card);
});
contentArea.appendChild(gridDiv);
});
}
}
window.switchWebsiteView = function(mode) {
currentViewMode = mode;
localStorage.setItem('website_view_mode', mode);
renderWebsites();
};
// MookNote 弹窗逻辑
let currentImageIndex = 0;
const mooknoteImages = document.querySelectorAll('.carousel-image');
const totalImages = mooknoteImages.length;
// 全屏预览相关变量
let lightboxImageIndex = 0;
const lightboxImgUrls = [
'./static/img/my_work/mooknote/banner.jpg',
'./static/img/my_work/mooknote/1.jpg',
'./static/img/my_work/mooknote/2.jpg',
'./static/img/my_work/mooknote/3.jpg',
'./static/img/my_work/mooknote/4.jpg',
'./static/img/my_work/mooknote/5.jpg',
'./static/img/my_work/mooknote/6.jpg'
];
// 初始化指示器
function initCarouselIndicators() {
const indicatorsContainer = document.querySelector('.carousel-indicators');
if (!indicatorsContainer) return;
indicatorsContainer.innerHTML = '';
for (let i = 0; i < totalImages; i++) {
const indicator = document.createElement('div');
indicator.className = 'carousel-indicator' + (i === 0 ? ' active' : '');
indicator.onclick = () => goToMooknoteImage(i);
indicatorsContainer.appendChild(indicator);
}
}
// 切换到指定图片
function goToMooknoteImage(index) {
if (index < 0) index = totalImages - 1;
if (index >= totalImages) index = 0;
mooknoteImages.forEach((img, i) => {
img.classList.toggle('active', i === index);
});
const indicators = document.querySelectorAll('.carousel-indicator');
indicators.forEach((indicator, i) => {
indicator.classList.toggle('active', i === index);
});
currentImageIndex = index;
}
// 上一张图片
window.prevMooknoteImage = function() {
goToMooknoteImage(currentImageIndex - 1);
};
// 下一张图片
window.nextMooknoteImage = function() {
goToMooknoteImage(currentImageIndex + 1);
};
// 全屏预览功能
window.openMooknoteLightbox = function(index) {
lightboxImageIndex = index;
const lightbox = document.querySelector('.mooknote-lightbox');
const img = lightbox.querySelector('.lightbox-img');
const counter = lightbox.querySelector('.lightbox-counter');
img.src = lightboxImgUrls[index];
counter.textContent = `${index + 1} / ${lightboxImgUrls.length}`;
lightbox.classList.add('active');
};
window.closeMooknoteLightbox = function() {
const lightbox = document.querySelector('.mooknote-lightbox');
lightbox.classList.remove('active');
};
window.prevLightboxImage = function() {
lightboxImageIndex = (lightboxImageIndex - 1 + lightboxImgUrls.length) % lightboxImgUrls.length;
updateLightboxImage();
};
window.nextLightboxImage = function() {
lightboxImageIndex = (lightboxImageIndex + 1) % lightboxImgUrls.length;
updateLightboxImage();
};
function updateLightboxImage() {
const lightbox = document.querySelector('.mooknote-lightbox');
const img = lightbox.querySelector('.lightbox-img');
const counter = lightbox.querySelector('.lightbox-counter');
img.src = lightboxImgUrls[lightboxImageIndex];
counter.textContent = `${lightboxImageIndex + 1} / ${lightboxImgUrls.length}`;
}
// 键盘事件支持
document.addEventListener('keydown', (e) => {
const lightbox = document.querySelector('.mooknote-lightbox');
if (!lightbox || !lightbox.classList.contains('active')) return;
if (e.key === 'Escape') {
closeMooknoteLightbox();
} else if (e.key === 'ArrowLeft') {
prevLightboxImage();
} else if (e.key === 'ArrowRight') {
nextLightboxImage();
}
});
function openMookNoteModal() {
const modal = document.getElementById('mooknote-modal');
if (modal) {
modal.classList.add('active');
document.body.style.overflow = 'hidden';
// 重置轮播到第一张
currentImageIndex = 0;
initCarouselIndicators();
goToMooknoteImage(0);
}
}
const mooknoteClose = document.getElementById('mooknote-close');
if (mooknoteClose) {
mooknoteClose.addEventListener('click', () => {
const modal = document.getElementById('mooknote-modal');
if (modal) {
modal.classList.remove('active');
document.body.style.overflow = '';
}
});
}
// ========== 初始化 (可选) ==========
// 如果你想在 DOM 加载完成后自动渲染,可以取消下面的注释
/*
document.addEventListener("DOMContentLoaded", function () {
renderWebsites(); // 不传参数,默认使用 websitesData
});
*/