Merge origin/main into dev (second round)
Resolve 21 conflicts from latest main (provider profiles, Windows fixes, 0.1.55-rc.1). Fix all type errors and syntax issues from merge artifacts.
This commit is contained in:
@@ -83,6 +83,7 @@ import {
|
||||
decodeWorkspaceIdFromPathSegment,
|
||||
} from "@/utils/host-routes";
|
||||
import { syncNavigationActiveWorkspace } from "@/stores/navigation-active-workspace-store";
|
||||
import { isWeb, isNative } from "@/constants/platform";
|
||||
|
||||
polyfillCrypto();
|
||||
|
||||
@@ -92,6 +93,22 @@ export type HostRuntimeBootstrapState = {
|
||||
retry: () => void;
|
||||
};
|
||||
|
||||
function getRouteParamValue(value: string | string[] | undefined): string | undefined {
|
||||
if (typeof value === "string") {
|
||||
const trimmed = value.trim();
|
||||
return trimmed.length > 0 ? trimmed : undefined;
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
const firstValue = value[0];
|
||||
if (typeof firstValue !== "string") {
|
||||
return undefined;
|
||||
}
|
||||
const trimmed = firstValue.trim();
|
||||
return trimmed.length > 0 ? trimmed : undefined;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const HostRuntimeBootstrapContext = createContext<HostRuntimeBootstrapState>({
|
||||
phase: "starting-daemon",
|
||||
error: null,
|
||||
@@ -103,7 +120,7 @@ function PushNotificationRouter() {
|
||||
const lastHandledIdRef = useRef<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (Platform.OS === "web") {
|
||||
if (isWeb) {
|
||||
let removeDesktopNotificationListener: (() => void) | null = null;
|
||||
let cancelled = false;
|
||||
|
||||
@@ -392,10 +409,10 @@ function AppContainer({
|
||||
const screenW = UnistylesRuntime.screen.width;
|
||||
const screenH = UnistylesRuntime.screen.height;
|
||||
const isElectron = getIsElectronRuntime();
|
||||
const windowW = Platform.OS === "web" ? window.innerWidth : undefined;
|
||||
const windowH = Platform.OS === "web" ? window.innerHeight : undefined;
|
||||
const dpr = Platform.OS === "web" ? window.devicePixelRatio : undefined;
|
||||
const ua = Platform.OS === "web" ? navigator.userAgent : undefined;
|
||||
const windowW = isWeb ? window.innerWidth : undefined;
|
||||
const windowH = isWeb ? window.innerHeight : undefined;
|
||||
const dpr = isWeb ? window.devicePixelRatio : undefined;
|
||||
const ua = isWeb ? navigator.userAgent : undefined;
|
||||
|
||||
console.log(
|
||||
"[layout-debug]",
|
||||
@@ -580,7 +597,7 @@ function ProvidersWrapper({ children }: { children: ReactNode }) {
|
||||
}, [settingsLoading, settings.theme]);
|
||||
|
||||
useEffect(() => {
|
||||
if (settingsLoading || Platform.OS !== "web") {
|
||||
if (settingsLoading || isNative) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -789,7 +806,14 @@ function RootStack() {
|
||||
<Stack.Screen name="settings" />
|
||||
<Stack.Screen name="pair-scan" />
|
||||
</Stack.Protected>
|
||||
<Stack.Screen name="h/[serverId]/workspace/[workspaceId]" />
|
||||
<Stack.Screen
|
||||
name="h/[serverId]/workspace/[workspaceId]"
|
||||
getId={({ params }) => {
|
||||
const serverId = getRouteParamValue(params?.serverId);
|
||||
const workspaceId = getRouteParamValue(params?.workspaceId);
|
||||
return serverId && workspaceId ? `${serverId}:${workspaceId}` : undefined;
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen name="h/[serverId]/agent/[agentId]" options={{ gestureEnabled: false }} />
|
||||
<Stack.Screen name="h/[serverId]/index" />
|
||||
<Stack.Screen name="h/[serverId]/sessions" />
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { useGlobalSearchParams, useLocalSearchParams, usePathname, useRootNavigationState } from "expo-router";
|
||||
import { Platform } from "react-native";
|
||||
import {
|
||||
useGlobalSearchParams,
|
||||
useLocalSearchParams,
|
||||
usePathname,
|
||||
useRootNavigationState,
|
||||
} from "expo-router";
|
||||
import { HostRouteBootstrapBoundary } from "@/components/host-route-bootstrap-boundary";
|
||||
import type { WorkspaceTabTarget } from "@/stores/workspace-tabs-store";
|
||||
import { WorkspaceScreen } from "@/screens/workspace/workspace-screen";
|
||||
@@ -11,6 +15,7 @@ import {
|
||||
type WorkspaceOpenIntent,
|
||||
} from "@/utils/host-routes";
|
||||
import { prepareWorkspaceTab } from "@/utils/workspace-navigation";
|
||||
import { isWeb } from "@/constants/platform";
|
||||
|
||||
function getParamValue(value: string | string[] | undefined): string {
|
||||
if (typeof value === "string") {
|
||||
@@ -91,7 +96,7 @@ function HostWorkspaceLayoutContent() {
|
||||
// Expo Router's replace ignores query-param-only changes (findDivergentState
|
||||
// skips search params). Strip ?open from the browser URL directly so the
|
||||
// address bar reflects the clean workspace route.
|
||||
if (Platform.OS === "web" && typeof window !== "undefined") {
|
||||
if (isWeb && typeof window !== "undefined") {
|
||||
const url = new URL(window.location.href);
|
||||
if (url.searchParams.has("open")) {
|
||||
url.searchParams.delete("open");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { Alert, Platform, Pressable, Text, View } from "react-native";
|
||||
import { Alert, Pressable, Text, View } from "react-native";
|
||||
import { useLocalSearchParams, useRouter } from "expo-router";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||
@@ -10,6 +10,7 @@ import { decodeOfferFragmentPayload, normalizeHostPort } from "@/utils/daemon-en
|
||||
import { connectToDaemon } from "@/utils/test-daemon-connection";
|
||||
import { ConnectionOfferSchema } from "@server/shared/connection-offer";
|
||||
import { buildHostRootRoute, buildHostSettingsRoute } from "@/utils/host-routes";
|
||||
import { isWeb } from "@/constants/platform";
|
||||
|
||||
const styles = StyleSheet.create((theme) => ({
|
||||
container: {
|
||||
@@ -198,7 +199,7 @@ export default function PairScanScreen() {
|
||||
}, [router, source, sourceServerId, targetServerId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (Platform.OS === "web") return;
|
||||
if (isWeb) return;
|
||||
if (permission && permission.granted) return;
|
||||
void requestPermission().catch(() => undefined);
|
||||
}, [permission, requestPermission]);
|
||||
@@ -253,7 +254,7 @@ export default function PairScanScreen() {
|
||||
[daemons, isPairing, returnToSource, targetServerId, upsertDaemonFromOfferUrl],
|
||||
);
|
||||
|
||||
if (Platform.OS === "web") {
|
||||
if (isWeb) {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={[styles.header, { paddingTop: insets.top + theme.spacing[2] }]}>
|
||||
|
||||
Reference in New Issue
Block a user