diff --git a/apps/mobile/src/features/home/HomeScreen.tsx b/apps/mobile/src/features/home/HomeScreen.tsx
index 2ae486cb64ab..e8ab5a492958 100644
--- a/apps/mobile/src/features/home/HomeScreen.tsx
+++ b/apps/mobile/src/features/home/HomeScreen.tsx
@@ -1140,6 +1140,22 @@ export function HomeScreen(props: HomeScreenProps) {
listEmpty
);
+ // T3-CUSTOM(expbkt3): BEGIN — the experimental phase sidebar replaces the
+ // whole list. This MUST sit above the threadListV2Enabled return below:
+ // that flag defaults to true, so anything after it is unreachable.
+ if (phaseSidebarEnabled) {
+ return (
+
+
+
+ );
+ }
+ // T3-CUSTOM(expbkt3): END
+
if (threadListV2Enabled) {
return (
@@ -1186,23 +1202,6 @@ export function HomeScreen(props: HomeScreenProps) {
);
}
- // T3-CUSTOM(expbkt3): BEGIN — the experimental phase sidebar replaces this
- // list entirely when enabled. It has to be wired here as well as in
- // ThreadNavigationSidebar: that pane only renders in split view, so on a
- // phone (compact layout) this screen IS the thread list.
- if (phaseSidebarEnabled) {
- return (
-
-
-
- );
- }
- // T3-CUSTOM(expbkt3): END
-
return (
{/* Sticky headers are deliberately not wired up: LegendList's JS sticky
diff --git a/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx b/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
index 5308019ebc0e..7d2a242d0fe7 100644
--- a/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
+++ b/apps/mobile/src/features/threads/ThreadNavigationSidebar.tsx
@@ -1264,6 +1264,22 @@ function ThreadNavigationSidebarPane(
);
}
+ // T3-CUSTOM(expbkt3): BEGIN — the experimental sidebar replaces this render
+ // path too. The nativeChrome branch above has its own copy; both paths render
+ // a thread list, so gating only one leaves the flag half-wired.
+ if (phaseSidebarEnabled) {
+ return (
+
+
+
+ );
+ }
+ // T3-CUSTOM(expbkt3): END
+
return (
` suffix and the version-skew check the fork depends on was blind.
+// Tests mock this module instead, which is what the rest of the suite does.
+import Constants from "expo-constants";
-function expoConfigExtra(): unknown {
- try {
- const loaded = require("expo-constants") as {
- readonly default?: { readonly expoConfig?: { readonly extra?: unknown } };
- readonly expoConfig?: { readonly extra?: unknown };
- };
- return (loaded.default ?? loaded).expoConfig?.extra;
- } catch {
- return null;
- }
-}
+import { readBkGitSha } from "./bkBuildIdentity";
export function bkBuildGitSha(): string | null {
- return readBkGitSha(expoConfigExtra());
+ return readBkGitSha(Constants.expoConfig?.extra);
}
diff --git a/apps/mobile/src/lib/connection.test.ts b/apps/mobile/src/lib/connection.test.ts
index a76db40a49f7..36ec8a7f4976 100644
--- a/apps/mobile/src/lib/connection.test.ts
+++ b/apps/mobile/src/lib/connection.test.ts
@@ -1,4 +1,9 @@
import { afterEach, describe, expect, it, vi } from "vite-plus/test";
+
+// T3-CUSTOM(expbkt3): authClientMetadata reads the Expo manifest for the fork
+// build SHA, which pulls in expo-modules-core; that reads React Native's
+// `__DEV__` global at import time and vitest does not define it.
+vi.mock("expo-constants", () => ({ default: { expoConfig: null } }));
import { EnvironmentId } from "@t3tools/contracts";
import {