// ==================== 闲言碎语 API 加载与分页功能 ==================== (function () { // 确保使用 HTTPS const MEMOS_API_BASE = "https://memos.iletter.top/api/v1/memos"; const PAGE_SIZE = 5; // 每页加载的 memo 数量 let memoData = []; // 存储所有已加载的 memo let allLoaded = false; // 标记是否已加载所有数据 let isLoading = false; // 标记是否正在加载,防止重复请求 let nextPageToken = null; // 用于 API 分页的 token // 获取 DOM 元素 const memosTab = document.querySelector('.nav-tab[data-tab="memos"]'); const memosContainer = document.getElementById("memos-container"); const memosContent = document.getElementById("memos-content"); // 日期格式化函数 (简单实现) function formatDate(dateStr) { const date = new Date(dateStr); return date.toLocaleString("sv-SE"); // 使用瑞典格式,结果接近 '2026-01-08 00:57:04' } // 渲染 Memo 列表 (追加模式) function renderMemos(memos) { if (!memos || memos.length === 0) { // 如果是首次加载且无数据 if (memoData.length === 0) { memosContainer.innerHTML = '
暂无数据
'; } return; } let html = ""; memos.forEach((memo) => { const formattedDate = formatDate(memo.displayTime); const tagsHtml = memo.tags && memo.tags.length > 0 ? `
${memo.tags .map((tag) => `${tag}`) .join("")}
` : ""; // 去掉 \n# 及其后面的部分 const contentWithoutHash = memo.content.split("\n#")[0]; // --- 新增: 生成附件 HTML --- let attachmentsHtml = ""; if ( memo.attachments && Array.isArray(memo.attachments) && memo.attachments.length > 0 ) { attachmentsHtml = '
'; memo.attachments.forEach((attachment) => { // 检查附件类型是否为图片 if (attachment.type && attachment.type.startsWith("image/")) { // 构造缩略图链接 const thumbnailUrl = `https://memos.iletter.top/file/${attachment.name }/${encodeURIComponent(attachment.filename)}?thumbnail=true`; attachmentsHtml += `
${attachment.filename
                            }
`; } // 如果需要处理其他类型的附件,可以在这里添加 else if 分支 else { attachmentsHtml += `${attachment.filename }`; } }); attachmentsHtml += "
"; } html += `
${formattedDate}
${contentWithoutHash}
${attachmentsHtml} ${tagsHtml}
`; }); // 如果是首次加载,则替换容器内容 if (memoData.length === memos.length) { memosContainer.innerHTML = html; } else { // 否则追加到现有内容之后 memosContainer.insertAdjacentHTML("beforeend", html); } } // 加载 Memo 数据 (分页) - 修正后的函数 async function loadMemos() { // 防止重复加载或已加载完毕时再次加载 if (isLoading || allLoaded) { console.log("加载状态检查:", { isLoading, allLoaded }); return; } isLoading = true; // 显示加载状态 (仅在首次加载时替换,后续加载追加) if (memoData.length === 0) { memosContainer.innerHTML = '
正在加载...
'; } try { // 构建 API 请求 URL,确保 pageToken 不为 null 时才添加 const url = new URL(MEMOS_API_BASE); url.searchParams.set("pageSize", PAGE_SIZE.toString()); url.searchParams.set("orderBy", "display_time desc"); if (nextPageToken) { url.searchParams.set("pageToken", nextPageToken); } // console.log("请求 URL:", url.toString()); // 调试信息 const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); // console.log("API 响应:", data); // 调试信息 const newMemos = data.memos || []; memoData = memoData.concat(newMemos); // --- 修复的关键逻辑 --- // 检查 API 返回的 next_page_token 是否为空字符串 if (data.nextPageToken === "") { allLoaded = true; // 标记为已全部加载 nextPageToken = null; // 清空 token console.log("检测到 nextPageToken 为空,已全部加载。"); } else { // 如果不为空,更新 token 以供下次使用 nextPageToken = data.nextPageToken; } // 渲染新加载的数据 renderMemos(newMemos); // --- 修复的关键逻辑 --- // 只有在尚未全部加载完时,才渲染加载更多按钮 if (!allLoaded) { renderLoadMoreButton(); } else { const loadMoreContainer = document.getElementById("load-more-btn"); if (loadMoreContainer) { loadMoreContainer.remove(); } // 数据全部加载完后,可以显示一个提示 memosContainer.insertAdjacentHTML( "beforeend", '
已加载全部数据
' ); } } catch (error) { console.error("加载闲言碎语失败:", error); // 如果是首次加载失败,替换内容 if (memoData.length === 0) { memosContainer.innerHTML = `
加载失败: ${error.message}
`; } else { // 如果是追加加载失败,提示错误,但保留已有内容 memosContainer.insertAdjacentHTML( "beforeend", `
加载失败: ${error.message}
` ); } } finally { isLoading = false; } } // 渲染“加载更多”按钮 function renderLoadMoreButton() { const existingButton = document.getElementById("load-more-btn"); if (existingButton) existingButton.remove(); const loadMoreButton = document.createElement("div"); loadMoreButton.id = "load-more-btn"; loadMoreButton.className = "memo-pagination"; loadMoreButton.innerHTML = ``; memosContainer.appendChild(loadMoreButton); } // 为加载更多按钮绑定事件 (使用全局函数) window.loadMemos = loadMemos; // 当“闲言碎语”标签被点击时加载数据 memosTab.addEventListener("click", function () { // 只有在内容是空的或者首次加载时才调用 if (memoData.length === 0) { loadMemos(); } }); })();