From 472b7f06fcac852611fb47ba3d404202e9fc343d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=AD=E6=B5=A9?= Date: Fri, 7 Aug 2026 00:11:35 +0800 Subject: [PATCH] clarify presenter timer controls --- assets/template-swiss.html | 4 ++-- assets/template.html | 4 ++-- references/checklist.md | 2 +- references/presenter-mode.md | 2 +- scripts/validate-presenter-mode.mjs | 3 +++ 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/assets/template-swiss.html b/assets/template-swiss.html index 70ff265..76ec15a 100644 --- a/assets/template-swiss.html +++ b/assets/template-swiss.html @@ -1756,7 +1756,7 @@ window.__pptPresenter=(()=>{
演讲者视图
观众屏 · 未连接
当前页
下一页
标题
本页目的
草稿(备注)
已保存
-
已进行00:00总时长
本页00:00计划 —
计划—未设置
+
已进行00:00总时长
本页00:00计划 —
计划—未设置
`); document.getElementById('ppt-reopen').onclick=reopenAudience; @@ -1828,7 +1828,7 @@ window.__pptPresenter=(()=>{ if(plan)plan.textContent=totalPlan?`计划 ${Number(totalPlan/60000).toFixed(1)} 分钟 · 预计 ${clockTime(Date.now()+Math.max(0,totalPlan-totalUsed))}`:'计划 —'; const section=sectionInfo(idx),sectionEl=document.getElementById('ppt-section'); if(sectionEl){sectionEl.hidden=!section;sectionEl.textContent=section?`${section.name} · ${section.position}/${section.count}${section.planned?` · 剩余 ${durationText(Math.max(0,section.planned-section.used))}`:''}`:'';} - const timerButton=document.getElementById('ppt-timer-toggle');if(timerButton)timerButton.textContent=timerRunning?'暂停':(totalUsed?'继续':'开始'); + const timerButton=document.getElementById('ppt-timer-toggle');if(timerButton)timerButton.textContent=timerRunning?'暂停':(totalUsed?'继续计时':'开始计时'); const rehearsalButton=document.getElementById('ppt-rehearsal');if(rehearsalButton){rehearsalButton.textContent=rehearsalActive?'结束排练':'排练';rehearsalButton.classList.toggle('ppt-rehearsal-on',rehearsalActive);} renderAutoState(); } diff --git a/assets/template.html b/assets/template.html index 1322a62..230e076 100644 --- a/assets/template.html +++ b/assets/template.html @@ -933,7 +933,7 @@ window.__pptPresenter=(()=>{
演讲者视图
观众屏 · 未连接
当前页
下一页
标题
本页目的
草稿(备注)
已保存
-
已进行00:00总时长
本页00:00计划 —
计划—未设置
+
已进行00:00总时长
本页00:00计划 —
计划—未设置
`); document.getElementById('ppt-reopen').onclick=reopenAudience; @@ -1005,7 +1005,7 @@ window.__pptPresenter=(()=>{ if(plan)plan.textContent=totalPlan?`计划 ${Number(totalPlan/60000).toFixed(1)} 分钟 · 预计 ${clockTime(Date.now()+Math.max(0,totalPlan-totalUsed))}`:'计划 —'; const section=sectionInfo(idx),sectionEl=document.getElementById('ppt-section'); if(sectionEl){sectionEl.hidden=!section;sectionEl.textContent=section?`${section.name} · ${section.position}/${section.count}${section.planned?` · 剩余 ${durationText(Math.max(0,section.planned-section.used))}`:''}`:'';} - const timerButton=document.getElementById('ppt-timer-toggle');if(timerButton)timerButton.textContent=timerRunning?'暂停':(totalUsed?'继续':'开始'); + const timerButton=document.getElementById('ppt-timer-toggle');if(timerButton)timerButton.textContent=timerRunning?'暂停':(totalUsed?'继续计时':'开始计时'); const rehearsalButton=document.getElementById('ppt-rehearsal');if(rehearsalButton){rehearsalButton.textContent=rehearsalActive?'结束排练':'排练';rehearsalButton.classList.toggle('ppt-rehearsal-on',rehearsalActive);} renderAutoState(); } diff --git a/references/checklist.md b/references/checklist.md index d24fa16..8eaa029 100644 --- a/references/checklist.md +++ b/references/checklist.md @@ -16,7 +16,7 @@ - 演讲入口只放在右下角现有快捷控制区,显示 `P 演讲模式`。 - 演讲者主体只做“左侧预览 + 右侧备注”两栏;当前页在上、下一页在下,避免形成挤压当前页的三栏布局。 - 两个预览 iframe 必须严格保持 `16:9`,容器不足时等比缩小并留边,不得裁切或拉伸;小屏优先压缩下一页预览高度。 -- 底栏固定为“左时间、中控制、右页码进度”:左侧分组显示已进行/本页/剩余或超时,中间两行放翻页和会话控制,右侧只放页码与百分比;不要重复当前页标题。 +- 底栏固定为“左时间、中控制、右页码进度”:左侧分组显示已进行/本页/剩余或超时,中间两行放翻页和会话控制,右侧只放页码与百分比;不要重复当前页标题。会话控制使用“开始计时 / 继续计时 / 重置计时 / 排练”等明确动作名,不使用孤立的“开始”或“重置”。 - 翻页控制顺序固定为 `首页 / 上一页 / 下一页 / 尾页`;尾页时最后一个按钮变为“重新开始”。自动翻页放在右上角状态栏。 - `宫格` 放在当前页标题旁,打开时替换当前/下一页预览区;选中页面后回到预览,不要弹出突兀的全屏总览。 - 右侧卡片依次显示标题、本页目的和草稿备注;设置里的开关用胶囊 switch,时间间隔用美化后的加减 stepper。 diff --git a/references/presenter-mode.md b/references/presenter-mode.md index 3efd956..91305a3 100644 --- a/references/presenter-mode.md +++ b/references/presenter-mode.md @@ -93,7 +93,7 @@ window.__SPEAKER_NOTES__ = SPEAKER_NOTES; - 主体保持两栏:左侧预览、右侧备注;左侧当前页在上、下一页在下。 - 当前页与下一页 iframe 始终严格保持 `16:9`。空间不足时留边并整体等比缩小,不得裁切、压扁或让页面内部文字重新排版。 - 小屏优先缩小下一页预览,把空间留给当前页。 -- 底栏分成三段:左侧是 `已进行 / 本页 / 剩余或超时` 三组时间,中间是两行控制(第一行 `首页 / 上一页 / 下一页 / 尾页`,第二行 `开始或暂停 / 重置 / 排练`),右侧只显示 `第几页 / 总页数` 和完成百分比。不要在底栏重复当前页标题。 +- 底栏分成三段:左侧是 `已进行 / 本页 / 剩余或超时` 三组时间,中间是两行控制(第一行 `首页 / 上一页 / 下一页 / 尾页`,第二行 `开始计时或暂停 / 重置计时 / 排练`),右侧只显示 `第几页 / 总页数` 和完成百分比。不要在底栏重复当前页标题。计时按钮必须明确写成“开始计时 / 继续计时 / 重置计时”,避免让用户误以为是重置整场演示。 - `自动翻页` 放在右上角状态栏,不占用底部翻页区。 - `宫格` 放在“当前页”标题旁。打开后直接用宫格替换当前页/下一页预览区,不要弹出突兀的全屏层;卡片显示页码、标题、章节和进度,点击页面后立即回到当前页/下一页预览。`ESC` 切换宫格。 - 右侧卡片依次显示 `标题 / 本页目的 / 草稿(备注)`,避免把标题或页面目的混进草稿正文。 diff --git a/scripts/validate-presenter-mode.mjs b/scripts/validate-presenter-mode.mjs index 75012e7..29db95b 100644 --- a/scripts/validate-presenter-mode.mjs +++ b/scripts/validate-presenter-mode.mjs @@ -113,6 +113,9 @@ const runtimeChecks=[ ['shortcut help','openShortcuts'], ]; for(const [label,needle]of runtimeChecks)if(!html.includes(needle))errors.push(`Presenter runtime missing ${label}.`); +if(!/id="ppt-timer-toggle"[^>]*>开始计时<\/button>/.test(html))errors.push('Presenter timer must use the explicit label "开始计时".'); +if(!/id="ppt-timer-reset"[^>]*>重置计时<\/button>/.test(html))errors.push('Presenter timer reset must use the explicit label "重置计时".'); +if(!html.includes("totalUsed?'继续计时':'开始计时'"))errors.push('Presenter timer resume state must use the explicit label "继续计时".'); if(/\.ppt-preview-stack\{[^}]*grid-template-columns/.test(html))errors.push('Presenter previews must stack vertically; remove grid-template-columns from .ppt-preview-stack.'); const timedNotes=speakerNotes.filter(n=>Number.isFinite(Number(n?.minutes))&&Number(n.minutes)>0);