Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
79ad856
fix(mobile): align iOS segmented controls with action colors (#20721)
juliusmarminge Oct 17, 2026
5c5dcbc
perf(web): the pull requests page compiles with the React Compiler (#…
juliusmarminge Oct 17, 2026
23163fd
perf(web): the legacy sidebar compiles with the React Compiler (#20640)
juliusmarminge Oct 17, 2026
3cb1330
perf(client): a repository identity refresh keeps unchanged projects …
juliusmarminge Oct 17, 2026
a702563
perf(web): the new-thread handler keeps its identity across provider …
juliusmarminge Oct 17, 2026
f29640d
perf(web): the linked pull requests panel compiles without manual mem…
juliusmarminge Oct 17, 2026
311319e
perf(web): pull request markdown compiles without manual memoization …
juliusmarminge Oct 17, 2026
f1dccf2
perf(web): the pull request label and reviewer pickers compile withou…
juliusmarminge Oct 17, 2026
0241bbf
perf(web): the usage state hook compiles without manual memoization (…
juliusmarminge Oct 17, 2026
d2213c8
perf(web): the pull request guide tab compiles without manual memoiza…
juliusmarminge Oct 17, 2026
7c74a35
perf(web): the shell command block compiles without manual memoizatio…
juliusmarminge Oct 17, 2026
f43206d
perf(web): the composer draft store compiles without manual memoizati…
juliusmarminge Oct 17, 2026
b84a591
perf(web): the hosted prompt link landing compiles without manual mem…
juliusmarminge Oct 17, 2026
6805b64
perf(web): the model picker compiles without manual memoization (#20711)
juliusmarminge Oct 17, 2026
82a99f7
perf(web): the pull request state hooks compile without manual memoiz…
juliusmarminge Oct 17, 2026
4e8b5ee
perf(web): discovered local servers compile without manual memoizatio…
juliusmarminge Oct 17, 2026
dab2d5c
perf(web): the proposed plan card compiles without manual memoization…
juliusmarminge Oct 17, 2026
ce29ba9
perf(web): the pull request link hooks compile without manual memoiza…
juliusmarminge Oct 17, 2026
40b325b
perf(web): the preview mini player compiles without manual memoizatio…
juliusmarminge Oct 17, 2026
19a760c
perf(web): file entry icons compile without manual memoization (#20703)
juliusmarminge Oct 17, 2026
b413396
perf(web): toasts compile without manual memoization (#20702)
juliusmarminge Oct 17, 2026
c0cdb02
perf(web): the thread action menu hook compiles without manual memoiz…
juliusmarminge Oct 17, 2026
07956d1
perf(web): the new thread hooks compile without manual memoization (#…
juliusmarminge Oct 17, 2026
73d9a77
perf(web): the open-in picker compiles without manual memoization (#2…
juliusmarminge Oct 17, 2026
26a7df0
perf(web): the file save coordinator compiles without manual memoizat…
juliusmarminge Oct 17, 2026
b103346
perf(web): the combobox compiles without manual memoization (#20696)
juliusmarminge Oct 17, 2026
b190a2f
perf(web): the usage provider chart compiles without manual memoizati…
juliusmarminge Oct 17, 2026
39bcf7c
perf(web): the usage model dialog compiles without manual memoization…
juliusmarminge Oct 17, 2026
c712852
perf(web): update everything compiles without manual memoization (#20…
juliusmarminge Oct 17, 2026
06299ff
perf(web): the file preview panel compiles with the React Compiler (#…
juliusmarminge Oct 17, 2026
38b4357
perf(web): the MCP app frame compiles without manual memoization (#20…
juliusmarminge Oct 17, 2026
49c51bb
perf(web): main app navigation compiles without manual memoization (#…
juliusmarminge Oct 17, 2026
daf4643
perf(web): project file queries compile without manual memoization (#…
juliusmarminge Oct 17, 2026
4539e77
perf(web): the HTML render frame compiles without manual memoization …
juliusmarminge Oct 17, 2026
9e88a4f
perf(web): the sidebar update capsule compiles without manual memoiza…
juliusmarminge Oct 17, 2026
3c6df71
perf(web): the terminal session hooks compile without manual memoizat…
juliusmarminge Oct 17, 2026
6ad62b8
perf(web): the project file picker compiles without manual memoizatio…
juliusmarminge Oct 17, 2026
72b3340
perf(web): the sidebar chrome compiles without manual memoization (#2…
juliusmarminge Oct 17, 2026
41edad8
perf(web): the file context menu hooks compile without manual memoiza…
juliusmarminge Oct 17, 2026
2ff8e74
perf(web): the snapshot shortcut recorder compiles without manual mem…
juliusmarminge Oct 17, 2026
2a337fe
perf(web): the pull request linking hook compiles without manual memo…
juliusmarminge Oct 17, 2026
66eee62
perf(web): the port discovery hooks compile without manual memoizatio…
juliusmarminge Oct 17, 2026
dc060b1
perf(web): the new-thread link route compiles without manual memoizat…
juliusmarminge Oct 17, 2026
2643821
perf(web): the Electron browser host compiles with the React Compiler…
juliusmarminge Oct 17, 2026
d859445
perf(web): the CSV table preview compiles without manual memoization …
juliusmarminge Oct 17, 2026
8e49f23
perf(web): the thread lineage panel compiles without manual memoizati…
juliusmarminge Oct 17, 2026
de9756a
perf(web): the open panel pull request URL hook compiles without manu…
juliusmarminge Oct 17, 2026
cba00ae
perf(web): highlighted code tokens compile without manual memoization…
juliusmarminge Oct 17, 2026
383d8cc
perf(web): scoped settings hooks compile without manual memoization (…
juliusmarminge Oct 17, 2026
c5310c2
perf(web): the HTML document frame compiles without manual memoizatio…
juliusmarminge Oct 17, 2026
36c1fe5
perf(web): the new project hook compiles without manual memoization (…
juliusmarminge Oct 17, 2026
165fa98
perf(web): the scratch project hook compiles without manual memoizati…
juliusmarminge Oct 17, 2026
92b8967
perf(web): the expanded image dialog compiles without manual memoizat…
juliusmarminge Oct 17, 2026
d209e56
perf(web): the sidebar project groups hook compiles without manual me…
juliusmarminge Oct 17, 2026
9439b1a
perf(web): review file patches compile without manual memoization (#2…
juliusmarminge Oct 17, 2026
436ff01
perf(web): the draft hero headline compiles without manual memoizatio…
juliusmarminge Oct 17, 2026
3f5c16f
perf(web): settings project groups compile without manual memoization…
juliusmarminge Oct 17, 2026
3ba121e
perf(web): the chat route layout compiles without manual memoization …
juliusmarminge Oct 17, 2026
aca2b2a
perf(web): scoped model availability compiles without manual memoizat…
juliusmarminge Oct 17, 2026
e3a578f
perf(web): the environment hooks compile without manual memoization (…
juliusmarminge Oct 17, 2026
11f6676
perf(web): the provider settings panel compiles with the React Compil…
juliusmarminge Oct 17, 2026
15a8774
perf(web): the code block language picker compiles without manual mem…
juliusmarminge Oct 17, 2026
afb8da0
perf(web): the right panel tabs compile with the React Compiler (#20662)
juliusmarminge Oct 17, 2026
934398b
perf(web): settings search availability compiles without manual memoi…
juliusmarminge Oct 17, 2026
37db94e
perf(web): the editor preference hooks compile without manual memoiza…
juliusmarminge Oct 17, 2026
99fac26
perf(web): the code view file reveal hook compiles without manual mem…
juliusmarminge Oct 17, 2026
35548e2
perf(web): the command output panel compiles without manual memoizati…
juliusmarminge Oct 17, 2026
65d352e
perf(web): the annotatable diff view compiles without manual memoizat…
juliusmarminge Oct 17, 2026
4a9516d
perf(web): the chat header compiles with the React Compiler (#20656)
juliusmarminge Oct 17, 2026
a9fb608
perf(web): the theme library compiles with the React Compiler (#20655)
juliusmarminge Oct 17, 2026
4e8c01c
perf(web): the chat canvas compiles without manual memoization (#20654)
juliusmarminge Oct 17, 2026
d42681d
perf(web): useResizableWidth compiles without manual memoization (#20…
juliusmarminge Oct 17, 2026
c7fe6d3
perf(web): device controls compile without manual memoization (#20652)
juliusmarminge Oct 17, 2026
ec9f8e8
perf(web): file breadcrumbs compile with the React Compiler (#20651)
juliusmarminge Oct 17, 2026
c8b3ebf
perf(web): the changed files tree compiles without manual memoization…
juliusmarminge Oct 17, 2026
db2d0eb
perf(web): the provider update dismissal hook compiles without manual…
juliusmarminge Oct 17, 2026
472a62a
perf(web): the sidebar primitives compile with the React Compiler (#2…
juliusmarminge Oct 17, 2026
9b62eae
perf(web): the settings layout compiles without manual memoization (#…
juliusmarminge Oct 17, 2026
0ed3ae8
perf(web): the remote open hook compiles without manual memoization (…
juliusmarminge Oct 17, 2026
9578a59
perf(web): usePreviewBridge compiles with the React Compiler (#20644)
juliusmarminge Oct 17, 2026
b6dde72
perf(web): the citation chip compiles without manual memoization (#20…
juliusmarminge Oct 17, 2026
f63f026
perf(web): useHtmlRenderTheme compiles without manual memoization (#2…
juliusmarminge Oct 17, 2026
f22415a
perf(web): project content search compiles with the React Compiler (#…
juliusmarminge Oct 17, 2026
6a0587c
perf(web): the agent connect surface compiles without manual memoizat…
juliusmarminge Oct 17, 2026
909c2b5
Merge remote-tracking branch 'upstream/main' into sync/upstream-20261…
r4iju Oct 17, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ final class T3SegmentedControlView: ExpoView {
}
}
var selectedIndex = -1 { didSet { updateSelection() } }
var trackColor: UIColor = .secondarySystemBackground { didSet { control.backgroundColor = trackColor } }
var selectedColor: UIColor = .secondarySystemFill { didSet { control.selectedSegmentTintColor = selectedColor } }
var textColor: UIColor = .label { didSet { updateColors() } }
var mutedColor: UIColor = .secondaryLabel { didSet { updateColors() } }
var trackColor: UIColor = .secondarySystemBackground { didSet { if trackColor != oldValue { control.backgroundColor = trackColor } } }
var selectedColor: UIColor = .secondarySystemFill { didSet { if selectedColor != oldValue { control.selectedSegmentTintColor = selectedColor } } }
var textColor: UIColor = .label { didSet { if textColor != oldValue { updateColors() } } }
var mutedColor: UIColor = .secondaryLabel { didSet { if mutedColor != oldValue { updateColors() } } }
var appearance = "light" {
didSet { overrideUserInterfaceStyle = appearance == "dark" ? .dark : .light }
didSet {
guard appearance != oldValue else { return }
overrideUserInterfaceStyle = appearance == "dark" ? .dark : .light
}
}

required init(appContext: AppContext? = nil) {
Expand All @@ -31,11 +34,20 @@ final class T3SegmentedControlView: ExpoView {

override func layoutSubviews() {
super.layoutSubviews()
control.frame = bounds
guard control.frame != bounds else { return }
UIView.performWithoutAnimation {
control.frame = bounds
}
}

private func updateSelection() {
control.selectedSegmentIndex = labels.indices.contains(selectedIndex) ? selectedIndex : UISegmentedControl.noSegment
let index = labels.indices.contains(selectedIndex) ? selectedIndex : UISegmentedControl.noSegment
// React echoes native selections while UIKit is still settling the glass lens.
guard control.selectedSegmentIndex != index else { return }
UIView.performWithoutAnimation {
control.selectedSegmentIndex = index
control.layoutIfNeeded()
}
}

private func updateColors() {
Expand Down
6 changes: 3 additions & 3 deletions apps/mobile/src/components/ui/SegmentedControl.ios.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ export function SegmentedControl<Value extends string | number>(
) {
const { colors, colorScheme } = useControlTheme();
const trackColor = flattenThemeColor(
themeColorWithAlpha(colors["--color-primary"], colorScheme === "dark" ? 0.18 : 0.07),
themeColorWithAlpha(colors["--color-prominent-action"], colorScheme === "dark" ? 0.18 : 0.07),
colors["--color-screen"],
);
const selectedColor =
colorScheme === "dark" ? colors["--color-primary"] : colors["--color-secondary"];
colorScheme === "dark" ? colors["--color-prominent-action"] : colors["--color-secondary"];
const selectedTextColor =
colorScheme === "dark"
? colors["--color-primary-foreground"]
? colors["--color-prominent-action-foreground"]
: colors["--color-secondary-foreground"];
return (
<View className={props.className}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,6 @@ export function PullRequestRouteScreen({ route }: StaticScreenProps<PullRequestP
>
<PullRequestIdentity pr={identity} params={params} />
<SegmentedControl
className={Platform.OS === "android" ? undefined : "bg-grouped-card"}
options={[
{ value: "overview", label: "Overview" },
...(guidesEnabled
Expand Down
2 changes: 2 additions & 0 deletions apps/web/reactCompiledFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,6 @@ export const REACT_COMPILED_FILES = [
"apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx",
"apps/web/src/components/ThreadTerminalDrawer.tsx",
"apps/web/src/components/settings/SettingsPanels.tsx",
"apps/web/src/routes/_chat.pull-requests.tsx",
"apps/web/src/components/LegacySidebar.tsx",
] as const;
89 changes: 39 additions & 50 deletions apps/web/src/browser/ElectronBrowserHost.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
"use client";

import { parseScopedThreadKey } from "@t3tools/client-runtime/environment";
import { AuthPreviewOperateScope, FILL_PREVIEW_VIEWPORT } from "@t3tools/contracts";
import {
AuthPreviewOperateScope,
type DesktopPreviewOpenLinkEvent,
FILL_PREVIEW_VIEWPORT,
} from "@t3tools/contracts";
import { useAtomValue } from "@effect/atom-react";
import { type ComponentProps, useEffect, useMemo, useRef, useState } from "react";
import { type ComponentProps, useEffect, useEffectEvent, useState } from "react";

import { primaryEnvironmentIdAtom } from "~/state/primaryEnvironment";

import { isElectron } from "~/env";
import { useClientSettingsHydrated } from "~/hooks/useSettings";
import { useTheme } from "~/hooks/useTheme";
import { useActivePreviewSessions } from "~/previewStateStore";
import { previewEnvironment } from "~/state/preview";
import { useEnvironmentScope } from "~/state/session";
Expand All @@ -24,36 +27,27 @@ import { rendersServerTabNatively } from "./previewRuntime";
import { previewRuntimeTabId } from "./previewRuntimeTabId";

export function ElectronBrowserHost() {
const { resolvedTheme } = useTheme();
const previewByThreadKey = useActivePreviewSessions();
const primaryEnvironmentId = useAtomValue(primaryEnvironmentIdAtom);
const sessions = useMemo(
() =>
Object.entries(previewByThreadKey).flatMap(([threadKey, previewState]) => {
const threadRef = parseScopedThreadKey(threadKey);
return threadRef
? Object.values(previewState.sessions)
.filter(
(snapshot) =>
snapshot.runtime !== "server" ||
rendersServerTabNatively(threadRef.environmentId, primaryEnvironmentId, snapshot),
)
.map((snapshot) => ({
threadRef,
snapshot,
runtimeTabId: previewRuntimeTabId(
threadRef,
previewState.serverEpoch,
snapshot.tabId,
),
pictureInPicture:
previewState.desktopByTabId[snapshot.tabId]?.pictureInPicture ?? false,
zoomFactor: previewState.desktopByTabId[snapshot.tabId]?.zoomFactor ?? 1,
}))
: [];
}),
[previewByThreadKey, primaryEnvironmentId],
);
const sessions = Object.entries(previewByThreadKey).flatMap(([threadKey, previewState]) => {
const threadRef = parseScopedThreadKey(threadKey);
return threadRef
? Object.values(previewState.sessions)
.filter(
(snapshot) =>
snapshot.runtime !== "server" ||
rendersServerTabNatively(threadRef.environmentId, primaryEnvironmentId, snapshot),
)
.map((snapshot) => ({
threadRef,
snapshot,
runtimeTabId: previewRuntimeTabId(threadRef, previewState.serverEpoch, snapshot.tabId),
pictureInPicture:
previewState.desktopByTabId[snapshot.tabId]?.pictureInPicture ?? false,
zoomFactor: previewState.desktopByTabId[snapshot.tabId]?.zoomFactor ?? 1,
}))
: [];
});

useEffect(() => {
const preview = window.desktopBridge?.preview;
Expand Down Expand Up @@ -86,7 +80,7 @@ export function ElectronBrowserHost() {
observer.disconnect();
headObserver.disconnect();
};
}, [resolvedTheme]);
}, []);

useEffect(() => {
const preview = window.desktopBridge?.preview;
Expand All @@ -97,27 +91,22 @@ export function ElectronBrowserHost() {
}, []);

const openPreview = useAtomCommand(previewEnvironment.open, { reportFailure: true });
const sessionByRuntimeTabId = useRef(new Map<string, (typeof sessions)[number]>());
useEffect(() => {
sessionByRuntimeTabId.current = new Map(
sessions.map((session) => [session.runtimeTabId, session]),
);
}, [sessions]);
const onOpenLink = useEffectEvent(({ tabId, url, background }: DesktopPreviewOpenLinkEvent) => {
const source = sessions.find((session) => session.runtimeTabId === tabId);
if (!source) return;
void openUrlInPreview({
threadRef: source.threadRef,
url,
openPreview,
profileId: source.snapshot.profileId,
background,
});
});
useEffect(() => {
const preview = window.desktopBridge?.preview;
if (!preview) return;
return preview.onOpenLink(({ tabId, url, background }) => {
const source = sessionByRuntimeTabId.current.get(tabId);
if (!source) return;
void openUrlInPreview({
threadRef: source.threadRef,
url,
openPreview,
profileId: source.snapshot.profileId,
background,
});
});
}, [openPreview]);
return preview.onOpenLink(onOpenLink);
}, []);

if (!isElectron) return null;
return (
Expand Down
Loading
Loading