fix: refine heaven workspace controls
This commit is contained in:
+13
-9
@@ -424,9 +424,11 @@
|
||||
<small id="heavenStockSector">--</small>
|
||||
</div>
|
||||
</div>
|
||||
<button id="loadHeavenSelectionButton" class="button" type="button">载入</button>
|
||||
<button id="historyTrendButton" class="button" type="button"><i data-lucide="history"></i><span>历史记录</span></button>
|
||||
<button id="interpretTrendButton" class="button primary" type="button" disabled>解势</button>
|
||||
<div class="heaven-trend-actions">
|
||||
<button id="loadHeavenSelectionButton" class="button" type="button">载入</button>
|
||||
<button id="historyTrendButton" class="button" type="button"><i data-lucide="history"></i><span>历史记录</span></button>
|
||||
<button id="interpretTrendButton" class="button primary" type="button" disabled>解势</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="heavenTrendEmpty" class="heaven-trend-empty" role="status">请输入股票代码或股票名称</div>
|
||||
<div class="heaven-trend-layout" hidden>
|
||||
@@ -565,12 +567,14 @@
|
||||
<section id="heavenHeartPanel" class="heaven-panel">
|
||||
<canvas id="heartDustCanvas" class="heart-dust-canvas" aria-hidden="true"></canvas>
|
||||
<div id="heartLamp" class="heart-lamp" aria-hidden="true"></div>
|
||||
<button id="heartSoundToggle" class="heart-sound-toggle" type="button" aria-pressed="false" aria-label="开启观心声音">
|
||||
<i data-lucide="volume-x"></i><span>静音</span>
|
||||
</button>
|
||||
<button id="historyHeartButton" class="heart-history-button" type="button" aria-label="查看观心历史记录">
|
||||
<i data-lucide="history"></i><span>历史记录</span>
|
||||
</button>
|
||||
<div class="heart-toolbar-controls">
|
||||
<button id="historyHeartButton" class="heart-history-button" type="button" aria-label="查看观心历史记录" title="历史记录">
|
||||
<i data-lucide="history"></i><span>历史记录</span>
|
||||
</button>
|
||||
<button id="heartSoundToggle" class="heart-sound-toggle" type="button" aria-pressed="false" aria-label="开启观心声音" title="声音">
|
||||
<i data-lucide="volume-x"></i><span>静音</span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="heartRitualCurtain" class="heart-ritual-curtain" aria-hidden="true">
|
||||
<i class="heart-daybreak-dark"></i><strong>观 心</strong><span>心静,而后问</span>
|
||||
</div>
|
||||
|
||||
+51
-14
@@ -6037,7 +6037,21 @@ body.sidebar-collapsed .sidebar-collapse-button .lucide {
|
||||
|
||||
/* Heaven follow-up refinements */
|
||||
#heavenTrendPanel .heaven-controls {
|
||||
grid-template-columns: minmax(520px, 1fr) auto auto;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
}
|
||||
|
||||
.heaven-trend-actions {
|
||||
display: flex;
|
||||
align-items: end;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.heaven-trend-actions .button {
|
||||
width: auto;
|
||||
min-width: 72px;
|
||||
height: 40px;
|
||||
flex: 0 0 auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.heaven-stock-query {
|
||||
@@ -6130,7 +6144,7 @@ body.sidebar-collapsed .sidebar-collapse-button .lucide {
|
||||
|
||||
@media (max-width: 860px) {
|
||||
#heavenTrendPanel .heaven-controls {
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
|
||||
.heaven-stock-query {
|
||||
@@ -6147,6 +6161,18 @@ body.sidebar-collapsed .sidebar-collapse-button .lucide {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.heaven-trend-actions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.heaven-trend-actions .button {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding-right: 8px;
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.heaven-stock-identity {
|
||||
grid-template-columns: auto minmax(0, 1fr);
|
||||
}
|
||||
@@ -7760,7 +7786,7 @@ body.sidebar-collapsed .sidebar-collapse-button .lucide {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#heavenView #heavenHeartPanel > .heart-sound-toggle {
|
||||
#heavenView #heavenHeartPanel > .heart-toolbar-controls {
|
||||
width: auto;
|
||||
margin: 0;
|
||||
}
|
||||
@@ -9329,10 +9355,15 @@ body.sidebar-collapsed .sidebar-collapse-button .lucide {
|
||||
#heavenFortunePanel .fortune-heading-actions {
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
#heavenFortunePanel .fortune-heading-actions .qi-time-field {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
#heavenFortunePanel .fortune-heading-actions .button {
|
||||
width: 100%;
|
||||
grid-column: auto;
|
||||
}
|
||||
|
||||
@@ -10180,13 +10211,20 @@ body.sidebar-collapsed .sidebar-collapse-button .lucide {
|
||||
.heart-lamp[data-heart-stage="reveal"] { opacity: 1; top: 43%; }
|
||||
.heart-lamp[data-heart-stage="interpretation"] { opacity: 0.45; top: 35%; }
|
||||
|
||||
.heart-sound-toggle {
|
||||
min-width: 76px;
|
||||
min-height: 44px;
|
||||
.heart-toolbar-controls {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 14px;
|
||||
z-index: 8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.heart-sound-toggle,
|
||||
.heart-history-button {
|
||||
min-width: 76px;
|
||||
min-height: 36px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -11606,13 +11644,10 @@ button.account-role-badge:focus-visible { outline: 2px solid var(--blue); outlin
|
||||
}
|
||||
|
||||
.heart-history-button {
|
||||
min-height: 44px;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 102px;
|
||||
z-index: 8;
|
||||
min-height: 36px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 7px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid rgba(36, 40, 32, .18);
|
||||
@@ -11701,8 +11736,10 @@ button.account-role-badge:focus-visible { outline: 2px solid var(--blue); outlin
|
||||
.heaven-reading-history-detail footer { display: flex; justify-content: flex-end; margin-top: 28px; padding-top: 14px; border-top: 1px solid var(--border); }
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.heart-history-button { top: 8px; right: 60px; min-width: 42px; padding: 0 10px; }
|
||||
.heart-history-button span { display: none; }
|
||||
.heart-toolbar-controls { top: 8px; right: 8px; gap: 6px; }
|
||||
.heart-toolbar-controls .heart-sound-toggle,
|
||||
.heart-toolbar-controls .heart-history-button { width: 36px; min-width: 36px; min-height: 36px; padding: 0; }
|
||||
.heart-toolbar-controls span { display: none; }
|
||||
.heart-read-actions { flex-wrap: wrap; justify-content: flex-end; }
|
||||
.heaven-reading-dialog { width: calc(100vw - 16px); max-height: calc(100dvh - 16px); margin: 8px auto; }
|
||||
.heaven-reading-current { min-height: 360px; max-height: calc(100dvh - 150px); padding: 20px 17px 24px; }
|
||||
|
||||
@@ -354,3 +354,79 @@ test("reduced-motion preference suppresses continuous animation", async ({ page
|
||||
expect(Number.parseFloat(motion.duration)).toBeLessThanOrEqual(0.00001);
|
||||
expect(motion.iterations).toBe("1");
|
||||
});
|
||||
|
||||
test("heaven workspace actions remain compact and do not overlap", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 1440, height: 900 });
|
||||
await mockApplication(page, session("user", true));
|
||||
await page.goto("/index.html");
|
||||
await page.locator('[data-view="heavenView"]').first().click();
|
||||
|
||||
const titleSize = Number.parseFloat(await page.locator("#heavenView .heaven-toolbar h2").evaluate((element) => getComputedStyle(element).fontSize));
|
||||
expect(titleSize).toBeLessThanOrEqual(22);
|
||||
|
||||
const trendButtons = page.locator(".heaven-trend-actions .button");
|
||||
await expect(trendButtons).toHaveCount(3);
|
||||
for (let index = 0; index < await trendButtons.count(); index += 1) {
|
||||
const box = await trendButtons.nth(index).boundingBox();
|
||||
expect(box.width).toBeLessThanOrEqual(130);
|
||||
expect(box.height).toBeLessThanOrEqual(44);
|
||||
}
|
||||
await page.locator('[data-heaven-panel="fortune"]').click();
|
||||
const fortuneActions = await page.locator("#heavenFortunePanel .fortune-heading-actions").boundingBox();
|
||||
const fortunePanel = await page.locator("#heavenFortunePanel").boundingBox();
|
||||
expect(fortuneActions.x + fortuneActions.width).toBeLessThanOrEqual(fortunePanel.x + fortunePanel.width + 1);
|
||||
await page.evaluate(() => {
|
||||
state.heavenInterpretations.fortune = {
|
||||
id: 31,
|
||||
mode: "fortune",
|
||||
context_date: "20260723",
|
||||
subject: "2026-07-23 观气",
|
||||
subject_detail: "丙午年 · 乙未月 · 己丑日",
|
||||
answer: "三层气机已经合参,今日宜先定节奏,再看行动。",
|
||||
created_at: "2026-07-23T09:12:00+08:00",
|
||||
};
|
||||
openHeavenReading("fortune", { loading: false });
|
||||
});
|
||||
const readingDialog = await page.locator("#heavenReadingDialog").boundingBox();
|
||||
expect(readingDialog.width).toBeLessThanOrEqual(920);
|
||||
expect(readingDialog.height).toBeLessThanOrEqual(820);
|
||||
const readingHeader = await page.locator("#heavenReadingDialog .dialog-header").boundingBox();
|
||||
const readingTabs = await page.locator("#heavenReadingDialog .heaven-reading-tabs").boundingBox();
|
||||
expect(readingHeader.y + readingHeader.height).toBeLessThanOrEqual(readingTabs.y + 1);
|
||||
await page.locator("#closeHeavenReadingDialog").click();
|
||||
|
||||
await page.locator('[data-heaven-panel="heart"]').click();
|
||||
const heartControls = await page.locator(".heart-toolbar-controls").boundingBox();
|
||||
const heartPanel = await page.locator("#heavenHeartPanel").boundingBox();
|
||||
expect(heartControls.width).toBeLessThanOrEqual(190);
|
||||
expect(heartControls.x + heartControls.width).toBeLessThanOrEqual(heartPanel.x + heartPanel.width + 1);
|
||||
const historyBox = await page.locator("#historyHeartButton").boundingBox();
|
||||
const soundBox = await page.locator("#heartSoundToggle").boundingBox();
|
||||
expect(historyBox.width).toBeLessThanOrEqual(100);
|
||||
expect(historyBox.x + historyBox.width).toBeLessThanOrEqual(soundBox.x);
|
||||
|
||||
});
|
||||
|
||||
test("heaven workspace controls fit a narrow viewport", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 375, height: 812 });
|
||||
await mockApplication(page, session("user", true));
|
||||
await page.goto("/index.html");
|
||||
await page.locator('[data-view="heavenView"]').first().click();
|
||||
expect(await page.evaluate(() => window.scrollY)).toBe(0);
|
||||
|
||||
const trendActions = await page.locator(".heaven-trend-actions").boundingBox();
|
||||
expect(trendActions.width).toBeLessThanOrEqual(347);
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth - window.innerWidth)).toBeLessThanOrEqual(1);
|
||||
await page.locator('[data-heaven-panel="fortune"]').click();
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth - window.innerWidth)).toBeLessThanOrEqual(1);
|
||||
const fortuneButtons = page.locator("#heavenFortunePanel .fortune-heading-actions .button");
|
||||
const firstFortuneButton = await fortuneButtons.first().boundingBox();
|
||||
const secondFortuneButton = await fortuneButtons.last().boundingBox();
|
||||
expect(Math.abs(firstFortuneButton.width - secondFortuneButton.width)).toBeLessThanOrEqual(1);
|
||||
expect(Math.abs(firstFortuneButton.y - secondFortuneButton.y)).toBeLessThanOrEqual(1);
|
||||
await page.locator('[data-heaven-panel="heart"]').click();
|
||||
const heartControls = await page.locator(".heart-toolbar-controls").boundingBox();
|
||||
expect(heartControls.width).toBeLessThanOrEqual(80);
|
||||
expect(heartControls.x + heartControls.width).toBeLessThanOrEqual(375);
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth - window.innerWidth)).toBeLessThanOrEqual(1);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user