mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-14 03:56:55 +03:00
fix(app): keep the phone titlebar clear of the iOS status bar blur (#53297)
This commit is contained in:
committed by
GitHub
Unverified
parent
fad352c5d0
commit
eab83d63fd
@@ -30,9 +30,11 @@ for (const position of ["top", "bottom"] as const) {
|
||||
const navigation = page.locator('[data-slot="session-mobile-view-navigation"]')
|
||||
const more = navigation.getByRole("button", { name: "More options", exact: true })
|
||||
const picker = tabs.getByRole("tab", { selected: true })
|
||||
|
||||
const message = page.locator(
|
||||
`[data-timeline-row="UserMessage"][data-message-id="${fixture.expected.targetMessageIDs.at(-1)}"]`,
|
||||
)
|
||||
|
||||
const composer = page.getByRole("textbox", { name: "Prompt", exact: true })
|
||||
await expect(picker).toHaveText("Session")
|
||||
await expect(message).toBeVisible()
|
||||
@@ -40,9 +42,17 @@ for (const position of ["top", "bottom"] as const) {
|
||||
await expect(tabs.getByRole("tab")).toHaveText(["Session", "Changes", "Files", "Terminal"])
|
||||
await expect(tabs).toHaveCSS("padding-left", "0px")
|
||||
await expect(tabs).toHaveCSS("padding-right", "0px")
|
||||
|
||||
if (position === "top") {
|
||||
const titlebar = page.locator('[data-slot="titlebar-v2"]')
|
||||
await expect(titlebar).toHaveCSS("padding-top", "16px")
|
||||
await expect(titlebar).toHaveCSS("height", "44px")
|
||||
}
|
||||
|
||||
await expect
|
||||
.poll(async () => {
|
||||
const bounds = await navigation.boundingBox()
|
||||
|
||||
return !!bounds && bounds.x >= 8 && bounds.x <= 9 && bounds.width >= 372 && bounds.width <= 374
|
||||
})
|
||||
.toBe(true)
|
||||
@@ -51,6 +61,7 @@ for (const position of ["top", "bottom"] as const) {
|
||||
const bar = await tabs.boundingBox()
|
||||
const input = await composer.boundingBox()
|
||||
const panel = await page.locator('[data-slot="session-chat-panel"]').boundingBox()
|
||||
|
||||
return !!bar && !!input && !!panel && Math.abs(bar.y - panel.y) <= 1 && bar.y + bar.height <= input.y
|
||||
})
|
||||
.toBe(true)
|
||||
@@ -149,16 +160,19 @@ for (const position of ["top", "bottom"] as const) {
|
||||
|
||||
// The view resets to Session whenever the routed session changes, including through Home.
|
||||
const trigger = page.locator('[data-slot="mobile-tabs-trigger"]')
|
||||
|
||||
const openTabs = async () => {
|
||||
await trigger.click()
|
||||
await expect(drawer).not.toHaveAttribute("data-transitioning")
|
||||
}
|
||||
|
||||
const openTab = async (title: string) => {
|
||||
await openTabs()
|
||||
await drawer.locator('[data-slot="tab-link"]').filter({ hasText: title }).click()
|
||||
await expect(drawer).toBeHidden()
|
||||
await expect(trigger).toContainText(title)
|
||||
}
|
||||
|
||||
await more.click()
|
||||
await page.getByRole("menuitem", { name: "Usage", exact: true }).click()
|
||||
await expect(page.getByText("Total Cost", { exact: true })).toBeVisible()
|
||||
@@ -338,6 +352,7 @@ test.describe("touch", () => {
|
||||
.poll(async () => {
|
||||
const navigation = await settings.getByRole("button", { name: "Models", exact: true }).boundingBox()
|
||||
const content = await panel.boundingBox()
|
||||
|
||||
return !!navigation && !!content && navigation.y + navigation.height <= content.y
|
||||
})
|
||||
.toBe(true)
|
||||
|
||||
@@ -59,6 +59,7 @@ export function Titlebar(props: { verticalTabs?: { mount?: HTMLElement } }) {
|
||||
const location = useLocation()
|
||||
const mobile = createMediaQuery("(max-width: 767px)")
|
||||
const bottom = createMemo(() => mobile() && settings.general.mobileTitlebarPosition() === "bottom")
|
||||
const mobileTop = createMemo(() => platform.platform === "web" && mobile() && !bottom())
|
||||
|
||||
const mac = createMemo(() => platform.platform === "desktop" && platform.os === "macos")
|
||||
const windows = createMemo(() => platform.platform === "desktop" && platform.os === "windows")
|
||||
@@ -150,9 +151,17 @@ export function Titlebar(props: { verticalTabs?: { mount?: HTMLElement } }) {
|
||||
platform.platform === "web"
|
||||
? bottom()
|
||||
? "calc(28px + max(8px, var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px))))"
|
||||
: "calc(28px + max(8px, env(safe-area-inset-top, 0px)))"
|
||||
: mobileTop()
|
||||
? "calc(28px + 16px + env(safe-area-inset-top, 0px))"
|
||||
: "calc(28px + max(8px, env(safe-area-inset-top, 0px)))"
|
||||
: undefined,
|
||||
"padding-top": bottom() ? "0px" : "env(safe-area-inset-top, 0px)",
|
||||
// iOS blurs page content just below the status bar in Home Screen web apps, so keep the phone titlebar row
|
||||
// 16px clear of the safe area, as ChatGPT's phone header does.
|
||||
"padding-top": bottom()
|
||||
? "0px"
|
||||
: mobileTop()
|
||||
? "calc(16px + env(safe-area-inset-top, 0px))"
|
||||
: "env(safe-area-inset-top, 0px)",
|
||||
"padding-bottom": bottom() ? "var(--safe-area-inset-bottom, env(safe-area-inset-bottom, 0px))" : "0px",
|
||||
"min-height": minHeight(),
|
||||
// Keep native macOS traffic lights clear even when the desktop window is narrow.
|
||||
@@ -512,7 +521,7 @@ export function Titlebar(props: { verticalTabs?: { mount?: HTMLElement } }) {
|
||||
<div
|
||||
class="h-full flex-1 overflow-hidden flex flex-row items-center gap-1.5 px-2 md:pe-3"
|
||||
classList={{
|
||||
"pt-[max(0px,calc(8px-env(safe-area-inset-top,0px)))]": !bottom() && !windows(),
|
||||
"pt-[max(0px,calc(8px-env(safe-area-inset-top,0px)))]": !bottom() && !windows() && !mobileTop(),
|
||||
"pb-[max(0px,calc(8px-var(--safe-area-inset-bottom,env(safe-area-inset-bottom,0px))))]": bottom(),
|
||||
"pl-4": macTrafficLights(),
|
||||
// Center the 20px app icon over the sidebar's 16px icon column.
|
||||
|
||||
Reference in New Issue
Block a user