This commit is contained in:
QLHazyCoder
2026-04-21 19:01:00 +08:00
4 changed files with 75 additions and 24 deletions
+13 -11
View File
@@ -243,33 +243,35 @@ header {
color: var(--orange); color: var(--orange);
} }
.contribution-entry { .contribution-update-layer {
display: flex; position: fixed;
flex-direction: column; inset: 0;
align-items: flex-start; pointer-events: none;
gap: 6px; z-index: 1400;
position: relative;
} }
.contribution-update-hint { .contribution-update-hint {
position: relative; --contribution-update-arrow-left: 20px;
position: absolute;
top: 0;
left: 0;
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
gap: 8px; gap: 8px;
max-width: 220px; max-width: min(220px, calc(100vw - 24px));
margin-left: 6px;
padding: 8px 10px; padding: 8px 10px;
background: color-mix(in srgb, var(--amber) 10%, var(--bg-base)); background: color-mix(in srgb, var(--amber) 10%, var(--bg-base));
border: 1px solid color-mix(in srgb, var(--amber) 34%, var(--border)); border: 1px solid color-mix(in srgb, var(--amber) 34%, var(--border));
border-radius: 10px; border-radius: 10px;
box-shadow: var(--shadow-sm); box-shadow: var(--shadow-sm);
pointer-events: auto;
} }
.contribution-update-hint::before { .contribution-update-hint::before {
content: ''; content: '';
position: absolute; position: absolute;
top: -7px; top: -7px;
left: 14px; left: calc(var(--contribution-update-arrow-left) - 6px);
width: 12px; width: 12px;
height: 12px; height: 12px;
background: inherit; background: inherit;
@@ -436,7 +438,7 @@ header {
.run-group { .run-group {
display: flex; display: flex;
align-items: flex-start; align-items: center;
gap: 4px; gap: 4px;
flex-wrap: wrap; flex-wrap: wrap;
} }
+12 -11
View File
@@ -34,17 +34,8 @@
</div> </div>
<div class="header-btns"> <div class="header-btns">
<div class="run-group"> <div class="run-group">
<div class="contribution-entry"> <button id="btn-contribution-mode" class="btn btn-outline btn-sm btn-contribution-mode" type="button"
<button id="btn-contribution-mode" class="btn btn-outline btn-sm btn-contribution-mode" type="button" aria-pressed="false" title="进入贡献模式并打开上传页">贡献/使用</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>
<input type="number" id="input-run-count" class="run-count-input" value="1" min="1" max="50" title="运行次数" /> <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="自动执行全部步骤"> <button id="btn-auto-run" class="btn btn-success" title="自动执行全部步骤">
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"> <svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor">
@@ -90,6 +81,16 @@
</div> </div>
</header> </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> <section id="update-section" hidden>
<div class="update-card"> <div class="update-card">
<div class="update-card-header"> <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 btnStop = document.getElementById('btn-stop');
const btnReset = document.getElementById('btn-reset'); const btnReset = document.getElementById('btn-reset');
const btnContributionMode = document.getElementById('btn-contribution-mode'); const btnContributionMode = document.getElementById('btn-contribution-mode');
const contributionUpdateLayer = document.getElementById('contribution-update-layer');
const contributionUpdateHint = document.getElementById('contribution-update-hint'); const contributionUpdateHint = document.getElementById('contribution-update-hint');
const contributionUpdateHintText = document.getElementById('contribution-update-hint-text'); const contributionUpdateHintText = document.getElementById('contribution-update-hint-text');
const btnDismissContributionUpdateHint = document.getElementById('btn-dismiss-contribution-update-hint'); const btnDismissContributionUpdateHint = document.getElementById('btn-dismiss-contribution-update-hint');
@@ -2226,9 +2227,40 @@ function getContributionUpdateHintMessage(snapshot = currentContributionContentS
return '公告 / 使用教程有更新了,可点上方“贡献/使用”查看。'; 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) { function shouldShowContributionUpdateHint(snapshot = currentContributionContentSnapshot) {
const promptVersion = String(snapshot?.promptVersion || '').trim(); const promptVersion = String(snapshot?.promptVersion || '').trim();
if (!contributionUpdateHint || !contributionUpdateHintText || !btnContributionMode) { if (!contributionUpdateLayer || !contributionUpdateHint || !contributionUpdateHintText || !btnContributionMode) {
return false; return false;
} }
if (!promptVersion) { if (!promptVersion) {
@@ -2244,17 +2276,23 @@ function shouldShowContributionUpdateHint(snapshot = currentContributionContentS
} }
function renderContributionUpdateHint(snapshot = currentContributionContentSnapshot) { function renderContributionUpdateHint(snapshot = currentContributionContentSnapshot) {
if (!contributionUpdateHint) { if (!contributionUpdateLayer || !contributionUpdateHint) {
return; return;
} }
const visible = shouldShowContributionUpdateHint(snapshot); const visible = shouldShowContributionUpdateHint(snapshot);
contributionUpdateLayer.hidden = !visible;
contributionUpdateHint.hidden = !visible; contributionUpdateHint.hidden = !visible;
if (!visible || !contributionUpdateHintText) { if (!visible || !contributionUpdateHintText) {
return; return;
} }
contributionUpdateHintText.textContent = getContributionUpdateHintMessage(snapshot); contributionUpdateHintText.textContent = getContributionUpdateHintMessage(snapshot);
if (typeof window.requestAnimationFrame === 'function') {
window.requestAnimationFrame(() => positionContributionUpdateHint());
return;
}
positionContributionUpdateHint();
} }
function dismissContributionUpdateHint() { function dismissContributionUpdateHint() {
@@ -4720,6 +4758,14 @@ document.addEventListener('keydown', (event) => {
} }
}); });
window.addEventListener('resize', () => {
positionContributionUpdateHint();
});
document.addEventListener('scroll', () => {
positionContributionUpdateHint();
}, true);
// ============================================================ // ============================================================
// Init // Init
// ============================================================ // ============================================================
@@ -11,6 +11,8 @@ test('sidepanel html keeps a single contribution mode button in header', () => {
assert.equal(matches.length, 1); assert.equal(matches.length, 1);
assert.match(html, /id="btn-contribution-mode"[^>]*title="进入贡献模式并打开上传页"/); assert.match(html, /id="btn-contribution-mode"[^>]*title="进入贡献模式并打开上传页"/);
assert.match(html, />贡献\/使用<\/button>/); 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"/);
assert.match(html, /id="contribution-update-hint-text"/); assert.match(html, /id="contribution-update-hint-text"/);
assert.match(html, /id="btn-dismiss-contribution-update-hint"/); assert.match(html, /id="btn-dismiss-contribution-update-hint"/);