Skip to content
Merged
6 changes: 3 additions & 3 deletions apps/mobile/src/components/ui/useBarInset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ export function useBarOverlap(): number {
}

/**
* The content's top safe area under the AppBar: a translucent bar's height, zero under a solid
* one or on Android, where the bar sits in flow. For scroll content insets, which must not
* double-count a solid bar.
* The content's top safe area under the AppBar: the height of the iOS bar its column lays content
* under, glass or solid, and zero on Android, where the bar sits in flow. For manual scroll
* content insets.
*/
export function useContentTopInset(): number {
const insets = useSafeAreaInsets();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";

import { NATIVE_LIQUID_GLASS_SUPPORTED } from "../../../native/native-glass";

/** A workspace list scrolls under its bar where the bar is glass; under a solid bar it starts below. */
export const WORKSPACE_LIST_SCROLL_INSETS = {
automaticallyAdjustsScrollIndicatorInsets: NATIVE_LIQUID_GLASS_SUPPORTED,
contentInsetAdjustmentBehavior: NATIVE_LIQUID_GLASS_SUPPORTED ? "automatic" : "never",
} as const;

/** How far an empty workspace list keeps its message below a glass bar and its search. */
export function useWorkspaceListEmptyTopInset(): number {
const insets = useSafeAreaInsets();
Expand Down
1 change: 0 additions & 1 deletion apps/mobile/src/features/threads/ThreadDetailScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1496,7 +1496,6 @@ function ThreadDetailBody(
keyboardOffset={composerKeyboardOffset}
sendingWithKeyboard={sendingWithKeyboard}
fitShortFeedToViewport={questionInFlow && !isKeyboardVisible}
contentTopInset={0}
contentBottomInset={
questionInFlow
? 0
Expand Down
11 changes: 7 additions & 4 deletions apps/mobile/src/features/threads/ThreadFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ import { getReviewSectionIdForCheckpoint } from "../review/reviewModel";
import { setReviewSelectedSectionId } from "../review/reviewState";
import { Menu } from "../../components/ui/Menu";
import { useAndroidControlSizing } from "../../components/ui/useAndroidControlSizing";
import { useBarInset } from "../../components/ui/useBarInset";
import { useBarInset, useContentTopInset } from "../../components/ui/useBarInset";
import { copyPromptLink } from "../prompt-links/prompt-link-actions";
import { parseReviewCommentMessageSegments } from "../review/reviewCommentSelection";
import {
Expand Down Expand Up @@ -332,7 +332,6 @@ export interface ThreadFeedProps {
readonly keyboardOffset: number;
readonly sendingWithKeyboard?: boolean;
readonly fitShortFeedToViewport?: boolean;
readonly contentTopInset?: number;
readonly contentBottomInset?: number;
readonly historyControls?: ThreadFeedHistoryControls;
readonly contentMaxWidth?: number;
Expand Down Expand Up @@ -2772,10 +2771,12 @@ export const ThreadFeed = memo(function ThreadFeed(props: ThreadFeedProps) {
const markdownContentWidth = Math.max(0, contentWidth - ASSISTANT_ROW_HORIZONTAL_PADDING * 2);
const reviewCommentBubbleWidth = Math.min(Math.max(280, contentWidth * 0.85), contentWidth);
const barInset = useBarInset();
const topContentInset = props.contentTopInset ?? barInset;
const columnTopInset = useContentTopInset();
const bottomContentInset = props.contentBottomInset ?? 18;
const usesNativeAutomaticInsets =
props.usesAutomaticContentInsets === true && Platform.OS === "ios";
// Without the native contentInset, a list-header spacer clears the bar the column lays content under.
const topContentInset = usesNativeAutomaticInsets ? 0 : columnTopInset;
const anchorTopInset = usesNativeAutomaticInsets ? barInset : topContentInset;

const theme = useUniwindTheme();
Expand Down Expand Up @@ -3200,7 +3201,9 @@ export const ThreadFeed = memo(function ThreadFeed(props: ThreadFeedProps) {
if (state) onIsAtEndChange?.(state.isAtEnd);
};
const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {
reportHeaderMaterialVisibility(event.nativeEvent.contentOffset.y + anchorTopInset > 6);
reportHeaderMaterialVisibility(
event.nativeEvent.contentOffset.y + (usesNativeAutomaticInsets ? barInset : 0) > 6,
);
handleMetricsChange();
};
// oxlint-disable-next-line t3code/no-unreasoned-state-sync -- subscribes to the list's end state to report it to the parent
Expand Down
5 changes: 3 additions & 2 deletions apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import { usePendingTaskListActions } from "../home/usePendingTaskListActions";
import { useThreadListActions } from "../home/useThreadListActions";
import { useFabScroll } from "../home/FabScrollContext";
import { WorkspaceListHeader } from "../layout/workspace/WorkspaceListHeader";
import { WORKSPACE_LIST_SCROLL_INSETS } from "../layout/workspace/workspace-list-insets";
import { WorkspaceSidebarColumn } from "../layout/workspace/WorkspaceSidebarColumn";
import {
ThreadListV2PendingRow,
Expand Down Expand Up @@ -592,7 +591,9 @@ function ThreadNavigationSidebarPane(props: ThreadNavigationSidebarProps) {
itemsAreEqual={sidebarItemsAreEqual}
keyExtractor={(item) => item.key}
renderItem={renderListItem}
{...WORKSPACE_LIST_SCROLL_INSETS}
automaticallyAdjustsScrollIndicatorInsets
// The column lays the list under its bar, glass or solid; UIKit insets it past both.
contentInsetAdjustmentBehavior="automatic"
contentContainerStyle={[
styles.threadListContent,
{
Expand Down
Loading