fix: enlarge authenticated brand icon
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
## 状态与路由
|
## 状态与路由
|
||||||
|
|
||||||
应用启动先请求 `system/status`,已初始化时再请求 `auth/me`。未初始化渲染安装页;未登录渲染登录页;登录后由 `BrowserRouter` 提供 `/` 总览和 `/settings` 设置,未知路径回到 `/`。状态响应中的构建版本以 `v<version>` 徽标显示在安装页、登录页和登录后侧栏的品牌区域;品牌图标、名称和版本徽标保持单行排列。这些分支只负责交互,服务端 session 才是安全边界。
|
应用启动先请求 `system/status`,已初始化时再请求 `auth/me`。未初始化渲染安装页;未登录渲染登录页;登录后由 `BrowserRouter` 提供 `/` 总览和 `/settings` 设置,未知路径回到 `/`。状态响应中的构建版本以 `v<version>` 徽标显示在安装页、登录页和登录后侧栏的品牌区域;登录后侧栏使用放大的品牌图标,图标、名称和版本徽标保持单行排列。这些分支只负责交互,服务端 session 才是安全边界。
|
||||||
|
|
||||||
主题以服务端通用设置为持久来源,`localStorage` 仅用于首屏缓存;system 模式会跟随系统主题变化。当前账号 ID 保存到 `localStorage`。总览先加载账号列表,为当前账号加载 Dashboard,并在每轮请求完成 30 秒后刷新;切换账号会取消旧请求并校验响应账号,避免迟到响应覆盖当前账号。手动刷新调用账号级 sync 后重新读取 Dashboard。
|
主题以服务端通用设置为持久来源,`localStorage` 仅用于首屏缓存;system 模式会跟随系统主题变化。当前账号 ID 保存到 `localStorage`。总览先加载账号列表,为当前账号加载 Dashboard,并在每轮请求完成 30 秒后刷新;切换账号会取消旧请求并校验响应账号,避免迟到响应覆盖当前账号。手动刷新调用账号级 sync 后重新读取 Dashboard。
|
||||||
|
|
||||||
|
|||||||
@@ -230,6 +230,11 @@ aside {
|
|||||||
aside .logo {
|
aside .logo {
|
||||||
padding: 0 10px 28px;
|
padding: 0 10px 28px;
|
||||||
}
|
}
|
||||||
|
aside .logo svg {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
nav {
|
nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -49,10 +49,16 @@ const responses: Record<string, unknown> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
async function openSettings(page: Page) {
|
async function openSettings(page: Page, version = "0.3.0-beta.1") {
|
||||||
await page.route("**/api/v1/**", async (route) => {
|
await page.route("**/api/v1/**", async (route) => {
|
||||||
const key = new URL(route.request().url()).pathname.replace("/api/v1/", "");
|
const key = new URL(route.request().url()).pathname.replace("/api/v1/", "");
|
||||||
await new Promise((resolve) => setTimeout(resolve, 40));
|
await new Promise((resolve) => setTimeout(resolve, 40));
|
||||||
|
if (key === "system/status") {
|
||||||
|
await route.fulfill({
|
||||||
|
json: { initialized: true, appServer: true, version },
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
await route.fulfill({ json: responses[key] ?? {} });
|
await route.fulfill({ json: responses[key] ?? {} });
|
||||||
});
|
});
|
||||||
await page.goto("/settings");
|
await page.goto("/settings");
|
||||||
@@ -82,10 +88,34 @@ test("shows the build version in the authenticated brand", async ({ page }) => {
|
|||||||
badgeCenter: badgeRect.top + badgeRect.height / 2,
|
badgeCenter: badgeRect.top + badgeRect.height / 2,
|
||||||
nameCenter: nameRect.top + nameRect.height / 2,
|
nameCenter: nameRect.top + nameRect.height / 2,
|
||||||
iconCenter: iconRect.top + iconRect.height / 2,
|
iconCenter: iconRect.top + iconRect.height / 2,
|
||||||
|
iconWidth: iconRect.width,
|
||||||
|
iconHeight: iconRect.height,
|
||||||
|
iconFlexShrink: getComputedStyle(iconElement).flexShrink,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
expect(Math.abs(layout.badgeCenter - layout.nameCenter)).toBeLessThan(1);
|
expect(Math.abs(layout.badgeCenter - layout.nameCenter)).toBeLessThan(1);
|
||||||
expect(Math.abs(layout.iconCenter - layout.nameCenter)).toBeLessThan(1);
|
expect(Math.abs(layout.iconCenter - layout.nameCenter)).toBeLessThan(1);
|
||||||
|
expect(layout.iconWidth).toBe(30);
|
||||||
|
expect(layout.iconHeight).toBe(30);
|
||||||
|
expect(layout.iconFlexShrink).toBe("0");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("keeps the authenticated brand on one line with a release version", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
await openSettings(page, "0.2.0");
|
||||||
|
const brand = page.locator("aside .logo");
|
||||||
|
await expect(brand).toContainText("Codex Helper");
|
||||||
|
await expect(brand.locator(".version-badge")).toHaveText("v0.2.0");
|
||||||
|
const centers = await brand
|
||||||
|
.locator("svg, .brand-name, .version-badge")
|
||||||
|
.evaluateAll((elements) =>
|
||||||
|
elements.map((element) => {
|
||||||
|
const rect = element.getBoundingClientRect();
|
||||||
|
return rect.top + rect.height / 2;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
expect(Math.max(...centers) - Math.min(...centers)).toBeLessThan(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("shows the build version before setup", async ({ page }) => {
|
test("shows the build version before setup", async ({ page }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user