diff --git a/apps/mobile/src/features/threads/ThreadComposer.tsx b/apps/mobile/src/features/threads/ThreadComposer.tsx
index 3f5529b345f3a..54e142d6623ca 100644
--- a/apps/mobile/src/features/threads/ThreadComposer.tsx
+++ b/apps/mobile/src/features/threads/ThreadComposer.tsx
@@ -576,6 +576,7 @@ export const ThreadComposer = function ThreadComposer(props: ThreadComposerProps
const floatingSidebarComposer = useAndroidFloatingTabs() && layout.usesSplitView;
const usesLargeControls =
useSidebarWorkspaceTabs() === "picker" || (Platform.OS === "ios" && Platform.isPad);
+ const surfacePaddingVertical = usesLargeControls ? 9 : floatingSidebarComposer ? 6 : 2;
const [compactRowWidth, setCompactRowWidth] = useState(0);
const compactAttachmentLimit = compactRowWidth >= 500 ? 3 : 1;
const compactEditor = useCompactComposerEditor(bodyText, draftMessage);
@@ -871,7 +872,7 @@ export const ThreadComposer = function ThreadComposer(props: ThreadComposerProps
borderRadius: usesLargeControls ? 31 : 27,
borderCurve: "circular",
overflow: "hidden",
- paddingVertical: usesLargeControls ? 9 : floatingSidebarComposer ? 6 : 2,
+ paddingVertical: surfacePaddingVertical,
}}
>
{isExpanded ? editingAttachments : null}
@@ -1122,7 +1123,7 @@ export const ThreadComposer = function ThreadComposer(props: ThreadComposerProps
collapsable={false}
importantForAccessibility={isToolbarVisible ? "auto" : "no-hide-descendants"}
pointerEvents={isToolbarVisible ? "auto" : "none"}
- style={{ position: "absolute", bottom: usesLargeControls ? 9 : 2, left: 0, right: 0 }}
+ style={{ position: "absolute", bottom: surfacePaddingVertical, left: 0, right: 0 }}
>
{showStopAction ? (
) : showResumeAction && voicePresentation.showsSend ? (
) : voicePresentation.showsSend ? (
void;
readonly variant?: "plain" | "primary";
}) {
+ const { scale } = useAndroidControlSizing();
const variant = props.variant ?? "plain";
const loading = props.loading === true;
+ const large = props.size === "large";
+ const circleSize = Math.round((large ? 44 : 30) * scale);
+ const iconSize = Math.round(
+ (variant === "primary" ? (large ? 20 : 16) : large ? 24 : 20) * scale,
+ );
const primaryStyle = useAnimatedStyle(() => ({
opacity: withTiming(loading ? 0 : 1, DICTATION_TIMING),
}));
@@ -272,17 +279,18 @@ function VoiceActionButton(props: {
className="size-[44px] shrink-0 items-center justify-center active:opacity-70"
disabled={props.disabled}
onPress={props.onPress}
- style={{ opacity: props.disabled && !props.loading ? 0.4 : 1 }}
+ style={{
+ opacity: props.disabled && !props.loading ? 0.4 : 1,
+ // Matches ComposerActionButton so the circle stays concentric with the large composer corner.
+ width: variant === "primary" && large ? 62 : undefined,
+ }}
>
{variant === "primary" ? (