From 81e3570fb91497a323e4cecae4959272d5ff5991 Mon Sep 17 00:00:00 2001 From: Pixel Perfect Date: Mon, 12 Oct 2026 01:02:04 -0700 Subject: [PATCH 1/3] fix(android): space the New thread FAB 16dp from the edge and tab bar --- apps/mobile/src/features/home/AndroidHomeFab.android.tsx | 8 ++++---- apps/mobile/src/features/home/ThreadListToolbar.tsx | 9 ++++----- .../src/features/home/android-home-fab-position.ts | 7 +++++++ 3 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 apps/mobile/src/features/home/android-home-fab-position.ts diff --git a/apps/mobile/src/features/home/AndroidHomeFab.android.tsx b/apps/mobile/src/features/home/AndroidHomeFab.android.tsx index d8f4a218d6b8f..9a20686a748aa 100644 --- a/apps/mobile/src/features/home/AndroidHomeFab.android.tsx +++ b/apps/mobile/src/features/home/AndroidHomeFab.android.tsx @@ -12,6 +12,7 @@ import { useWorkspaceState } from "../../state/workspace"; import { FabScrollContext } from "./FabScrollContext"; import { updateFabScroll } from "./fab-scroll"; import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; +import { ANDROID_HOME_FAB_MARGIN, androidHomeFabBottom } from "./android-home-fab-position"; export function AndroidHomeFabLayout(props: ComponentProps) { const insets = useSafeAreaInsets(); @@ -42,11 +43,10 @@ export function AndroidHomeFabLayout(props: ComponentProps ) : null} diff --git a/apps/mobile/src/features/home/ThreadListToolbar.tsx b/apps/mobile/src/features/home/ThreadListToolbar.tsx index 298ab2903df32..4965ed8653e7b 100644 --- a/apps/mobile/src/features/home/ThreadListToolbar.tsx +++ b/apps/mobile/src/features/home/ThreadListToolbar.tsx @@ -22,6 +22,7 @@ import { WorkspaceConnectionTitle } from "./WorkspaceConnectionTitle"; import { useWorkspaceState } from "../../state/workspace"; import { useAndroidControlSizing } from "../../components/ui/useAndroidControlSizing"; import { useToolbarLayout } from "../../components/ui/useToolbarLayout"; +import { ANDROID_HOME_FAB_MARGIN, androidHomeFabBottom } from "./android-home-fab-position"; /** One toolbar height for the compact list and expanded sidebar, including search. */ export function ThreadListToolbar(props: { @@ -140,12 +141,10 @@ export function ThreadListToolbar(props: { {state.hasConnections ? ( diff --git a/apps/mobile/src/features/home/android-home-fab-position.ts b/apps/mobile/src/features/home/android-home-fab-position.ts new file mode 100644 index 0000000000000..f83e535062dab --- /dev/null +++ b/apps/mobile/src/features/home/android-home-fab-position.ts @@ -0,0 +1,7 @@ +// Material's FAB margin, in dp so it does not grow with the app's text size. +export const ANDROID_HOME_FAB_MARGIN = 16; + +/** Bottom offset shared by the New thread FAB and the filter button stacked above it. */ +export function androidHomeFabBottom(safeAreaBottom: number, sidebar: boolean | undefined) { + return sidebar ? Math.max(safeAreaBottom, 12) + 6 : safeAreaBottom + ANDROID_HOME_FAB_MARGIN; +} From dffd6f34efbba61f692e87babf5b3bd545f94b66 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Mon, 19 Oct 2026 01:39:44 +0000 Subject: [PATCH 2/3] fix(android): space the New thread FAB 16dp from the edge and tab bar The compact thread list positioned the FAB and the filter button above it with a rem-based `right-5` class, so the gap grew with the app's text size, and each control computed its bottom offset separately. Both now read one position from `androidHomeFabPosition` in dp: 16 from the right edge and safe-area-bottom + 16 on the compact list, the old offset in the sidebar. Co-Authored-By: Claude Fable 5.1 --- .../src/features/home/AndroidHomeFab.android.tsx | 11 +++++------ .../src/features/home/AndroidHomeFab.shared.tsx | 12 ++++++++++++ apps/mobile/src/features/home/ThreadListToolbar.tsx | 8 +++----- .../src/features/home/android-home-fab-position.ts | 7 ------- 4 files changed, 20 insertions(+), 18 deletions(-) delete mode 100644 apps/mobile/src/features/home/android-home-fab-position.ts diff --git a/apps/mobile/src/features/home/AndroidHomeFab.android.tsx b/apps/mobile/src/features/home/AndroidHomeFab.android.tsx index 9a20686a748aa..e8a29ce516c67 100644 --- a/apps/mobile/src/features/home/AndroidHomeFab.android.tsx +++ b/apps/mobile/src/features/home/AndroidHomeFab.android.tsx @@ -7,12 +7,14 @@ import { } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { NewThreadButton } from "../../components/NewThreadButton"; -import type { AndroidHomeFabLayout as SharedAndroidHomeFabLayout } from "./AndroidHomeFab.shared"; +import { + androidHomeFabPosition, + type AndroidHomeFabLayout as SharedAndroidHomeFabLayout, +} from "./AndroidHomeFab.shared"; import { useWorkspaceState } from "../../state/workspace"; import { FabScrollContext } from "./FabScrollContext"; import { updateFabScroll } from "./fab-scroll"; import { useAppearancePreferences } from "../settings/appearance/AppearancePreferencesProvider"; -import { ANDROID_HOME_FAB_MARGIN, androidHomeFabBottom } from "./android-home-fab-position"; export function AndroidHomeFabLayout(props: ComponentProps) { const insets = useSafeAreaInsets(); @@ -44,10 +46,7 @@ export function AndroidHomeFabLayout(props: ComponentProps ) : null} diff --git a/apps/mobile/src/features/home/AndroidHomeFab.shared.tsx b/apps/mobile/src/features/home/AndroidHomeFab.shared.tsx index 682bbd4591470..82c834a3c9558 100644 --- a/apps/mobile/src/features/home/AndroidHomeFab.shared.tsx +++ b/apps/mobile/src/features/home/AndroidHomeFab.shared.tsx @@ -8,3 +8,15 @@ export function AndroidHomeFabLayout(props: { }) { return <>{props.children}; } + +/** + * Where the New thread FAB sits; the filter button stacks on top of it from the same + * origin so the two cannot drift apart. In dp rather than a rem class so Material's + * 16dp margin does not grow with the app's text size. + */ +export function androidHomeFabPosition(safeAreaBottom: number, sidebar: boolean | undefined) { + return { + right: 16, + bottom: sidebar ? Math.max(safeAreaBottom, 12) + 6 : safeAreaBottom + 16, + }; +} diff --git a/apps/mobile/src/features/home/ThreadListToolbar.tsx b/apps/mobile/src/features/home/ThreadListToolbar.tsx index ce930d35eafbd..974f29b83b6b5 100644 --- a/apps/mobile/src/features/home/ThreadListToolbar.tsx +++ b/apps/mobile/src/features/home/ThreadListToolbar.tsx @@ -24,7 +24,7 @@ import { useWorkspaceState } from "../../state/workspace"; import { useAndroidControlSizing } from "../../components/ui/useAndroidControlSizing"; import { useToolbarLayout } from "../../components/ui/useToolbarLayout"; import { PullRequestGlyph } from "../pull-requests/pullRequestGlyphs"; -import { ANDROID_HOME_FAB_MARGIN, androidHomeFabBottom } from "./android-home-fab-position"; +import { androidHomeFabPosition } from "./AndroidHomeFab.shared"; /** One toolbar height for the compact list and expanded sidebar, including search. */ export function ThreadListToolbar(props: { @@ -47,6 +47,7 @@ export function ThreadListToolbar(props: { const listFocused = homeFocused && (workspace === null || workspace.state.selectedTab === "threads"); const { fabSize } = useAndroidControlSizing(); + const fab = androidHomeFabPosition(insets.bottom, props.sidebar); const { height: toolbarHeight, ...headerPadding } = useToolbarLayout(); const { state } = useWorkspaceState(); const { onRequestVisibility, onSearchQueryChange } = props; @@ -152,10 +153,7 @@ export function ThreadListToolbar(props: { {state.hasConnections ? ( {(open) => ( diff --git a/apps/mobile/src/features/home/android-home-fab-position.ts b/apps/mobile/src/features/home/android-home-fab-position.ts deleted file mode 100644 index f83e535062dab..0000000000000 --- a/apps/mobile/src/features/home/android-home-fab-position.ts +++ /dev/null @@ -1,7 +0,0 @@ -// Material's FAB margin, in dp so it does not grow with the app's text size. -export const ANDROID_HOME_FAB_MARGIN = 16; - -/** Bottom offset shared by the New thread FAB and the filter button stacked above it. */ -export function androidHomeFabBottom(safeAreaBottom: number, sidebar: boolean | undefined) { - return sidebar ? Math.max(safeAreaBottom, 12) + 6 : safeAreaBottom + ANDROID_HOME_FAB_MARGIN; -} From 4f83c53617504b347bc59efc7c84e1186adcff2f Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Mon, 19 Oct 2026 01:42:38 +0000 Subject: [PATCH 3/3] chore(mobile): tighten the FAB position comment Co-Authored-By: Claude Fable 5.1 --- apps/mobile/src/features/home/AndroidHomeFab.shared.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/mobile/src/features/home/AndroidHomeFab.shared.tsx b/apps/mobile/src/features/home/AndroidHomeFab.shared.tsx index 82c834a3c9558..5226fce97c2f3 100644 --- a/apps/mobile/src/features/home/AndroidHomeFab.shared.tsx +++ b/apps/mobile/src/features/home/AndroidHomeFab.shared.tsx @@ -10,9 +10,9 @@ export function AndroidHomeFabLayout(props: { } /** - * Where the New thread FAB sits; the filter button stacks on top of it from the same - * origin so the two cannot drift apart. In dp rather than a rem class so Material's - * 16dp margin does not grow with the app's text size. + * The filter button stacks on the New thread FAB from this same origin so the two + * cannot drift apart. In dp rather than a rem class so Material's 16dp margin does + * not grow with the app's text size. */ export function androidHomeFabPosition(safeAreaBottom: number, sidebar: boolean | undefined) { return {