Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/mobile/src/Stack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { useResolveClassNames } from "uniwind";

import { AppText as Text } from "./components/ui/AppText";
import { androidWorkspaceDestinationAnimation } from "./lib/android-workspace-navigation";
import { getCompactBrandHeaderOptions } from "./components/CompactBrandTitle";
import { getStageBadgeHeaderOptions } from "./components/HeaderStageBadge";
import { WorkspaceConnectionStatusProvider } from "./features/home/WorkspaceConnectionTitle";
import { WorkspaceRootScreen } from "./features/workspace/WorkspaceRootScreen";
import {
Expand Down Expand Up @@ -620,7 +620,7 @@ const RootStackConfig = createWorkspaceStackNavigator({
...FIXED_DUO_HEADER,
contentStyle: { backgroundColor: "transparent" },
headerBackVisible: false,
...getCompactBrandHeaderOptions(),
...getStageBadgeHeaderOptions(),
},
}),
PullRequest: createNativeStackScreen({
Expand Down
110 changes: 0 additions & 110 deletions apps/mobile/src/components/CompactBrandTitle.tsx

This file was deleted.

79 changes: 79 additions & 0 deletions apps/mobile/src/components/HeaderStageBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { NATIVE_WORKSPACE_COLUMNS_SUPPORTED } from "../native/NativeWorkspaceColumns";
import Constants from "expo-constants";
import type { NativeStackNavigationOptions } from "@react-navigation/native-stack";
import { Platform, View } from "react-native";

import { AppText as Text } from "./ui/AppText";
import { IPAD_HOME_TITLE_OFFSET } from "../lib/layoutMetrics";
import { resolveMobileStageLabel } from "../lib/mobileBranding";
import { useAndroidControlSizing } from "./ui/useAndroidControlSizing";

const BADGE_MAX_FONT_SCALE = 1.4;

export function headerTitleOffset(): number {
if (Platform.OS !== "ios") return 0;
return Platform.isPad && !NATIVE_WORKSPACE_COLUMNS_SUPPORTED ? IPAD_HOME_TITLE_OFFSET : 0;
}

/**
* The header's screen heading, visible only as the Dev or Nightly badge. Release builds still
* render this view: without it the native header falls back to its plain-text title.
*/
export function HeaderStageBadge(props: {
readonly screenTitle: string;
readonly allowFontScaling?: boolean;
}) {
const stageLabel = resolveMobileStageLabel(Constants.expoConfig?.extra?.appVariant);
const { scale } = useAndroidControlSizing();

return (
<View
aria-level={1}
accessibilityLabel={
stageLabel === null ? props.screenTitle : `${props.screenTitle}, ${stageLabel} build`
}
accessible
role="heading"
// Release builds draw nothing here; the frame still gives touch exploration a target.
className={stageLabel === null ? "h-11 w-24 self-start" : "self-start"}
style={{ marginLeft: headerTitleOffset() }}
>
{stageLabel === null ? null : (
<View
className="rounded-full bg-subtle px-1.5 py-0.5"
style={
Platform.OS === "android"
? { paddingHorizontal: 5.25 * scale, paddingVertical: 1.75 * scale }
: undefined
}
>
<Text
allowFontScaling={props.allowFontScaling}
maxFontSizeMultiplier={BADGE_MAX_FONT_SCALE}
className="font-t3-bold text-foreground-muted uppercase"
style={{ fontSize: 9 * scale, letterSpacing: 0.9 * scale }}
>
{stageLabel}
</Text>
</View>
)}
</View>
);
}

const THREADS_TITLE = "Threads";

function renderHeaderStageBadge() {
return <HeaderStageBadge allowFontScaling={Platform.OS === "ios"} screenTitle={THREADS_TITLE} />;
}

export function getStageBadgeHeaderOptions(
fallbackTitleStyle?: NativeStackNavigationOptions["headerTitleStyle"],
): NativeStackNavigationOptions {
return {
headerTitle: renderHeaderStageBadge,
headerTitleStyle: fallbackTitleStyle,
title: THREADS_TITLE,
unstable_headerLeftItems: undefined,
};
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
2 changes: 1 addition & 1 deletion apps/mobile/src/features/home/ThreadListToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ export function ThreadListToolbar(props: {
searchField={searchField}
onCloseSearch={closeSearch}
onOpenSearch={openSearch}
screenTitle="Threads"
searchAccessibilityLabel="Search threads"
titleAccessibilityLabel="T3 Code, Threads"
onOpenEnvironments={props.onOpenEnvironments}
filter={filterButton}
/>
Expand Down
14 changes: 7 additions & 7 deletions apps/mobile/src/features/home/WorkspaceConnectionTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { SymbolView } from "../../components/ui/AppSymbol";
import { AppText as Text } from "../../components/ui/AppText";
import { useAndroidControlSizing } from "../../components/ui/useAndroidControlSizing";
import {
brandTitleOffset,
CompactBrandTitle,
getCompactBrandHeaderOptions,
} from "../../components/CompactBrandTitle";
getStageBadgeHeaderOptions,
HeaderStageBadge,
headerTitleOffset,
} from "../../components/HeaderStageBadge";
import { useDeadlinePassed } from "../../lib/clock";
import { useWorkspaceState } from "../../state/workspace";
import {
Expand Down Expand Up @@ -169,13 +169,13 @@ export function getConnectionAwareBrandHeaderOptions(opts: {
const maxWidth = Math.max(0, opts.headerWidth - 64 - 44 * (opts.trailingItemCount ?? 1));

return {
...getCompactBrandHeaderOptions(opts.fallbackTitleStyle),
...getStageBadgeHeaderOptions(opts.fallbackTitleStyle),
headerTitle: () => (
<WorkspaceConnectionTitle
brand={<CompactBrandTitle />}
brand={<HeaderStageBadge screenTitle="Threads" />}
maxWidth={maxWidth}
onPress={opts.onOpenEnvironments}
statusOffset={brandTitleOffset()}
statusOffset={headerTitleOffset()}
/>
),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ export function PullRequestToolbar(props: {
}
onCloseSearch={closeSearch}
onOpenSearch={openSearch}
screenTitle="Pull requests"
searchAccessibilityLabel="Search pull requests"
titleAccessibilityLabel="T3 Code, Pull requests"
onOpenEnvironments={() => openSettings(navigation, "SettingsEnvironments")}
filter={
filters ? (
Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";
import type { SearchBarCommands } from "react-native-screens";

import { AppText as Text } from "../../components/ui/AppText";
import { CompactBrandTitle } from "../../components/CompactBrandTitle";
import { HeaderStageBadge } from "../../components/HeaderStageBadge";
import { Menu } from "../../components/ui/Menu";
import { SymbolView } from "../../components/ui/AppSymbol";
import { NATIVE_LIQUID_GLASS_SUPPORTED } from "../../native/native-glass";
Expand Down Expand Up @@ -865,7 +865,7 @@ function ThreadNavigationSidebarPane(
size="pageTitle"
brand={
<View className="h-11 flex-1 justify-center">
<CompactBrandTitle allowFontScaling={false} />
<HeaderStageBadge allowFontScaling={false} screenTitle="Threads" />
</View>
}
/>
Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/src/features/threads/sidebar-navigation-shell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { type NativeStackNavigationOptions } from "@react-navigation/native-stac
import type { ReactNode } from "react";
import { Platform } from "react-native";

import { getCompactBrandHeaderOptions } from "../../components/CompactBrandTitle";
import { getStageBadgeHeaderOptions } from "../../components/HeaderStageBadge";
import { NATIVE_LIQUID_GLASS_SUPPORTED } from "../../native/native-glass";
import { nativeHeaderScrollEdgeEffects } from "../../native/StackHeader";
import { useMobileNavigationTheme } from "../../lib/useMobileNavigationTheme";
Expand All @@ -22,7 +22,7 @@ const SIDEBAR_SCREEN_OPTIONS: SidebarScreenOptions = {
headerShadowVisible: false,
headerShown: true,
headerStyle: NATIVE_LIQUID_GLASS_SUPPORTED ? { backgroundColor: "transparent" } : undefined,
...getCompactBrandHeaderOptions({ fontSize: 18, fontWeight: "800" }),
...getStageBadgeHeaderOptions({ fontSize: 18, fontWeight: "800" }),
headerTransparent: NATIVE_LIQUID_GLASS_SUPPORTED,
scrollEdgeEffects: NATIVE_LIQUID_GLASS_SUPPORTED ? SCROLL_EDGE_EFFECTS : undefined,
unstable_navigationItemStyle: NATIVE_LIQUID_GLASS_SUPPORTED ? "editor" : undefined,
Expand Down
12 changes: 3 additions & 9 deletions apps/mobile/src/features/workspace/WorkspaceListToolbarRow.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ReactNode } from "react";
import { View } from "react-native";
import { AndroidHeaderIconButton } from "../../components/ui/AndroidScreenHeader";
import { CompactBrandTitle } from "../../components/CompactBrandTitle";
import { HeaderStageBadge } from "../../components/HeaderStageBadge";
import { useToolbarLayout } from "../../components/ui/useToolbarLayout";
import { WorkspaceConnectionTitle } from "../home/WorkspaceConnectionTitle";

Expand All @@ -17,7 +17,7 @@ export function WorkspaceListToolbarRow(props: {
readonly onCloseSearch: () => void;
readonly onOpenSearch: () => void;
readonly searchAccessibilityLabel: string;
readonly titleAccessibilityLabel: string;
readonly screenTitle: string;
readonly onOpenEnvironments: () => void;
/** Stays trailing while searching, so it never moves and still narrows the results. */
readonly filter: ReactNode;
Expand All @@ -41,13 +41,7 @@ export function WorkspaceListToolbarRow(props: {
<WorkspaceConnectionTitle
grow
onPress={props.onOpenEnvironments}
brand={
<CompactBrandTitle
allowFontScaling={false}
accessibilityLabel={props.titleAccessibilityLabel}
fit
/>
}
brand={<HeaderStageBadge allowFontScaling={false} screenTitle={props.screenTitle} />}
/>
</View>
<AndroidHeaderIconButton
Expand Down
4 changes: 2 additions & 2 deletions apps/mobile/src/features/workspace/WorkspaceRootScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Platform, View, useWindowDimensions } from "react-native";
import { useKeyboardState } from "react-native-keyboard-controller";
import { SafeAreaInsetsContext, useSafeAreaInsets } from "react-native-safe-area-context";

import { CompactBrandTitle } from "../../components/CompactBrandTitle";
import { HeaderStageBadge } from "../../components/HeaderStageBadge";
import { AndroidScreenHeader } from "../../components/ui/AndroidScreenHeader";
import { HeaderItemsWidthContext } from "../../native/header-items-width";
import { NativeStackScreenOptions } from "../../native/StackHeader";
Expand Down Expand Up @@ -64,7 +64,7 @@ function WorkspaceRootTitle(props: {
return (
<View style={{ width: maxWidth, minHeight: 32, justifyContent: "center" }}>
<WorkspaceConnectionTitle
brand={<CompactBrandTitle accessibilityLabel={`T3 Code, ${tabTitle}`} fit />}
brand={<HeaderStageBadge screenTitle={tabTitle} />}
maxWidth={maxWidth}
onPress={props.onOpenEnvironments}
/>
Expand Down
6 changes: 3 additions & 3 deletions apps/mobile/src/lib/mobileBranding.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type MobileStageLabel = "Beta" | "Dev" | "Nightly";
export type MobileStageLabel = "Dev" | "Nightly";

export function resolveMobileStageLabel(appVariant: unknown): MobileStageLabel {
export function resolveMobileStageLabel(appVariant: unknown): MobileStageLabel | null {
if (appVariant === "development") return "Dev";
if (appVariant === "preview") return "Nightly";
return "Beta";
return null;
}
Loading
Loading