mirror of
https://github.com/getpaseo/paseo.git
synced 2026-11-04 23:44:41 +00:00
fix(app): keep commits above the safe area (#4005)
The bottom-anchored commits section did not consume the device inset, so Android system navigation covered its disclosure row. Keep the inset with the section that owns that edge.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import React, { act } from "react";
|
||||
import { createRoot, type Root } from "react-dom/client";
|
||||
import { JSDOM } from "jsdom";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { CommitsSection } from "./commits-section";
|
||||
|
||||
vi.mock("react-native-unistyles", () => ({
|
||||
StyleSheet: {
|
||||
create: (factory: unknown) =>
|
||||
typeof factory === "function"
|
||||
? factory({
|
||||
borderRadius: { full: 9999, sm: 4 },
|
||||
borderWidth: { 1: 1 },
|
||||
colors: {
|
||||
border: "#333",
|
||||
foreground: "#fff",
|
||||
foregroundMuted: "#aaa",
|
||||
statusDanger: "#c33",
|
||||
surface2: "#222",
|
||||
},
|
||||
fontSize: { base: 15, sm: 13 },
|
||||
spacing: [0, 4, 8, 12],
|
||||
})
|
||||
: factory,
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("react-native-safe-area-context", () => ({
|
||||
useSafeAreaInsets: () => ({ top: 0, right: 0, bottom: 34, left: 0 }),
|
||||
}));
|
||||
|
||||
vi.mock("react-i18next", () => ({
|
||||
useTranslation: () => ({ t: (key: string) => key }),
|
||||
}));
|
||||
|
||||
vi.mock("@/git/use-commits-query", () => ({
|
||||
useCheckoutCommitsQuery: () => ({ status: "idle" }),
|
||||
}));
|
||||
|
||||
vi.mock("@/git/themed-chevron", () => ({
|
||||
ThemedChevron: () => null,
|
||||
chevronColorMapping: () => ({}),
|
||||
}));
|
||||
|
||||
vi.mock("./commit-row", () => ({
|
||||
CommitRow: () => null,
|
||||
}));
|
||||
|
||||
let root: Root | null = null;
|
||||
|
||||
beforeEach(() => {
|
||||
const dom = new JSDOM("<!doctype html><html><body></body></html>");
|
||||
vi.stubGlobal("React", React);
|
||||
vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
|
||||
vi.stubGlobal("window", dom.window);
|
||||
vi.stubGlobal("document", dom.window.document);
|
||||
vi.stubGlobal("HTMLElement", dom.window.HTMLElement);
|
||||
vi.stubGlobal("Node", dom.window.Node);
|
||||
vi.stubGlobal("navigator", dom.window.navigator);
|
||||
|
||||
const container = document.createElement("div");
|
||||
document.body.appendChild(container);
|
||||
root = createRoot(container);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
act(() => root?.unmount());
|
||||
root = null;
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
describe("CommitsSection", () => {
|
||||
it("keeps its bottom edge above the device safe area", () => {
|
||||
act(() => {
|
||||
root?.render(
|
||||
<CommitsSection serverId="server" cwd="/repo" onCommitPress={vi.fn()} collapsed />,
|
||||
);
|
||||
});
|
||||
|
||||
const header = document.querySelector('[data-testid="commits-section-header"]');
|
||||
expect(header?.parentElement?.getAttribute("style")).toContain("padding-bottom: 34px");
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { Pressable, Text, View } from "react-native";
|
||||
import { StyleSheet } from "react-native-unistyles";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useRetainedPanelActive } from "@/components/retained-panel";
|
||||
import { useCheckoutCommitsQuery, type CheckoutCommitsQueryResult } from "@/git/use-commits-query";
|
||||
@@ -91,6 +92,7 @@ export function CommitsSection({
|
||||
onCollapsedChange,
|
||||
}: CommitsSectionProps) {
|
||||
const { t } = useTranslation();
|
||||
const insets = useSafeAreaInsets();
|
||||
const isPanelActive = useRetainedPanelActive();
|
||||
const [now, setNow] = useState(() => new Date());
|
||||
const displayNow = useMemo(() => (isPanelActive ? new Date() : now), [isPanelActive, now]);
|
||||
@@ -119,6 +121,10 @@ export function CommitsSection({
|
||||
() => [styles.headerChevron, !collapsed && styles.headerChevronExpanded],
|
||||
[collapsed],
|
||||
);
|
||||
const containerStyle = useMemo(
|
||||
() => [styles.container, { paddingBottom: insets.bottom }],
|
||||
[insets.bottom],
|
||||
);
|
||||
|
||||
if (query.status === "unsupported") {
|
||||
return null;
|
||||
@@ -129,7 +135,7 @@ export function CommitsSection({
|
||||
: null;
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={containerStyle}>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
testID="commits-section-header"
|
||||
|
||||
Reference in New Issue
Block a user