feat: 添加贡献更新提示层,优化贡献模式按钮及相关提示功能

This commit is contained in:
QLHazyCoder
2026-04-21 18:11:07 +08:00
parent 5c75d2e3aa
commit 7bb51185ae
4 changed files with 75 additions and 24 deletions
+13 -11
View File
@@ -243,33 +243,35 @@ header {
color: var(--orange);
}
.contribution-entry {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 6px;
position: relative;
.contribution-update-layer {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 1400;
}
.contribution-update-hint {
position: relative;
--contribution-update-arrow-left: 20px;
position: absolute;
top: 0;
left: 0;
display: flex;
align-items: flex-start;
gap: 8px;
max-width: 220px;
margin-left: 6px;
max-width: min(220px, calc(100vw - 24px));
padding: 8px 10px;
background: color-mix(in srgb, var(--amber) 10%, var(--bg-base));
border: 1px solid color-mix(in srgb, var(--amber) 34%, var(--border));
border-radius: 10px;
box-shadow: var(--shadow-sm);
pointer-events: auto;
}
.contribution-update-hint::before {
content: '';
position: absolute;
top: -7px;
left: 14px;
left: calc(var(--contribution-update-arrow-left) - 6px);
width: 12px;
height: 12px;
background: inherit;
@@ -436,7 +438,7 @@ header {
.run-group {
display: flex;
align-items: flex-start;
align-items: center;
gap: 4px;
flex-wrap: wrap;
}
+12 -11
View File
@@ -34,17 +34,8 @@
</div>
<div class="header-btns">
<div class="run-group">
<div class="contribution-entry">
<button id="btn-contribution-mode" class="btn btn-outline btn-sm btn-contribution-mode" type="button"
aria-pressed="false" title="进入贡献模式并打开上传页">贡献/使用</button>
<div id="contribution-update-hint" class="contribution-update-hint" aria-live="polite" hidden>
<p id="contribution-update-hint-text" class="contribution-update-hint-text">
公告 / 使用教程有更新了,可点上方“贡献/使用”查看。
</p>
<button id="btn-dismiss-contribution-update-hint" class="contribution-update-hint-close" type="button"
aria-label="关闭更新提示" title="关闭更新提示">×</button>
</div>
</div>
<button id="btn-contribution-mode" class="btn btn-outline btn-sm btn-contribution-mode" type="button"
aria-pressed="false" title="进入贡献模式并打开上传页">贡献/使用</button>
<input type="number" id="input-run-count" class="run-count-input" value="1" min="1" max="50" title="运行次数" />
<button id="btn-auto-run" class="btn btn-success" title="自动执行全部步骤">
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
@@ -90,6 +81,16 @@
</div>
</header>
<div id="contribution-update-layer" class="contribution-update-layer" hidden>
<div id="contribution-update-hint" class="contribution-update-hint" aria-live="polite" hidden>
<p id="contribution-update-hint-text" class="contribution-update-hint-text">
公告 / 使用教程有更新了,可点上方“贡献/使用”查看。
</p>
<button id="btn-dismiss-contribution-update-hint" class="contribution-update-hint-close" type="button"
aria-label="关闭更新提示" title="关闭更新提示">×</button>
</div>
</div>
<section id="update-section" hidden>
<div class="update-card">
<div class="update-card-header">
+48 -2
View File
@@ -57,6 +57,7 @@ const btnSaveSettings = document.getElementById('btn-save-settings');
const btnStop = document.getElementById('btn-stop');
const btnReset = document.getElementById('btn-reset');
const btnContributionMode = document.getElementById('btn-contribution-mode');
const contributionUpdateLayer = document.getElementById('contribution-update-layer');
const contributionUpdateHint = document.getElementById('contribution-update-hint');
const contributionUpdateHintText = document.getElementById('contribution-update-hint-text');
const btnDismissContributionUpdateHint = document.getElementById('btn-dismiss-contribution-update-hint');
@@ -2220,9 +2221,40 @@ function getContributionUpdateHintMessage(snapshot = currentContributionContentS
return '公告 / 使用教程有更新了,可点上方“贡献/使用”查看。';
}
function positionContributionUpdateHint() {
if (!contributionUpdateLayer || !contributionUpdateHint || !btnContributionMode) {
return;
}
if (contributionUpdateLayer.hidden || contributionUpdateHint.hidden) {
return;
}
const buttonRect = btnContributionMode.getBoundingClientRect();
const viewportWidth = Math.max(document.documentElement?.clientWidth || 0, window.innerWidth || 0);
const viewportHeight = Math.max(document.documentElement?.clientHeight || 0, window.innerHeight || 0);
const hintWidth = contributionUpdateHint.offsetWidth || 220;
const hintHeight = contributionUpdateHint.offsetHeight || 56;
const viewportPadding = 12;
const gap = 10;
const maxLeft = Math.max(viewportPadding, viewportWidth - hintWidth - viewportPadding);
const left = Math.min(Math.max(viewportPadding, Math.round(buttonRect.left)), maxLeft);
const shouldPlaceAbove = (buttonRect.bottom + gap + hintHeight) > (viewportHeight - viewportPadding)
&& buttonRect.top > (hintHeight + gap + viewportPadding);
const top = shouldPlaceAbove
? Math.max(viewportPadding, Math.round(buttonRect.top - hintHeight - gap))
: Math.max(viewportPadding, Math.round(buttonRect.bottom + gap));
const buttonCenter = Math.round(buttonRect.left + (buttonRect.width / 2));
const arrowOffset = Math.min(Math.max(16, buttonCenter - left), Math.max(16, hintWidth - 16));
contributionUpdateHint.style.left = `${left}px`;
contributionUpdateHint.style.top = `${top}px`;
contributionUpdateHint.style.setProperty('--contribution-update-arrow-left', `${arrowOffset}px`);
}
function shouldShowContributionUpdateHint(snapshot = currentContributionContentSnapshot) {
const promptVersion = String(snapshot?.promptVersion || '').trim();
if (!contributionUpdateHint || !contributionUpdateHintText || !btnContributionMode) {
if (!contributionUpdateLayer || !contributionUpdateHint || !contributionUpdateHintText || !btnContributionMode) {
return false;
}
if (!promptVersion) {
@@ -2238,17 +2270,23 @@ function shouldShowContributionUpdateHint(snapshot = currentContributionContentS
}
function renderContributionUpdateHint(snapshot = currentContributionContentSnapshot) {
if (!contributionUpdateHint) {
if (!contributionUpdateLayer || !contributionUpdateHint) {
return;
}
const visible = shouldShowContributionUpdateHint(snapshot);
contributionUpdateLayer.hidden = !visible;
contributionUpdateHint.hidden = !visible;
if (!visible || !contributionUpdateHintText) {
return;
}
contributionUpdateHintText.textContent = getContributionUpdateHintMessage(snapshot);
if (typeof window.requestAnimationFrame === 'function') {
window.requestAnimationFrame(() => positionContributionUpdateHint());
return;
}
positionContributionUpdateHint();
}
function dismissContributionUpdateHint() {
@@ -4692,6 +4730,14 @@ document.addEventListener('keydown', (event) => {
}
});
window.addEventListener('resize', () => {
positionContributionUpdateHint();
});
document.addEventListener('scroll', () => {
positionContributionUpdateHint();
}, true);
// ============================================================
// Init
// ============================================================
@@ -11,6 +11,8 @@ test('sidepanel html keeps a single contribution mode button in header', () => {
assert.equal(matches.length, 1);
assert.match(html, /id="btn-contribution-mode"[^>]*title="进入贡献模式并打开上传页"/);
assert.match(html, />贡献\/使用<\/button>/);
assert.match(html, /<\/header>\s*<div id="contribution-update-layer"/);
assert.match(html, /id="contribution-update-layer"/);
assert.match(html, /id="contribution-update-hint"/);
assert.match(html, /id="contribution-update-hint-text"/);
assert.match(html, /id="btn-dismiss-contribution-update-hint"/);