Improve mobile selectors and sheet inputs
Keep sheet text inputs native-owned to avoid React Native controlled input flicker during fast typing. Add reset keys for fields that need programmatic clears, and move model, mode, and thinking pickers onto shared combobox rows with fuzzy ranked search and native virtualization.
This commit is contained in:
@@ -22,7 +22,7 @@ import { Alert } from "@/components/ui/alert";
|
||||
import { ExternalLink } from "@/components/ui/external-link";
|
||||
import { LoadingSpinner } from "@/components/ui/loading-spinner";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { AdaptiveModalSheet } from "@/components/adaptive-modal-sheet";
|
||||
import { AdaptiveModalSheet, type SheetHeader } from "@/components/adaptive-modal-sheet";
|
||||
import { SettingsGroup } from "@/screens/settings/settings-group";
|
||||
import { SettingsSection } from "@/screens/settings/settings-section";
|
||||
import { settingsStyles } from "@/styles/settings";
|
||||
@@ -1150,11 +1150,15 @@ function ScriptEditModal({ script, onChange, onCancel, onSave }: ScriptEditModal
|
||||
const showNameError = touched.name && validation.nameError;
|
||||
const showCommandError = touched.command && validation.commandError;
|
||||
const isService = script.type === SCRIPT_SERVICE_TYPE;
|
||||
const sheetHeader = useMemo<SheetHeader>(
|
||||
() => ({ title: script.name ? `Edit ${script.name}` : "New script" }),
|
||||
[script.name],
|
||||
);
|
||||
|
||||
return (
|
||||
<AdaptiveModalSheet
|
||||
visible
|
||||
title={script.name ? `Edit ${script.name}` : "New script"}
|
||||
header={sheetHeader}
|
||||
onClose={onCancel}
|
||||
testID="script-edit-modal"
|
||||
desktopMaxWidth={560}
|
||||
|
||||
@@ -18,7 +18,7 @@ import { confirmDialog } from "@/utils/confirm-dialog";
|
||||
import { settingsStyles } from "@/styles/settings";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
import { AdaptiveModalSheet } from "@/components/adaptive-modal-sheet";
|
||||
import { AdaptiveModalSheet, type SheetHeader } from "@/components/adaptive-modal-sheet";
|
||||
import { useDaemonConfig } from "@/hooks/use-daemon-config";
|
||||
import { useIsLocalDaemon } from "@/hooks/use-is-local-daemon";
|
||||
import { SettingsSection } from "@/screens/settings/settings-section";
|
||||
@@ -68,6 +68,10 @@ function formatDaemonVersionBadge(version: string | null): string | null {
|
||||
return trimmed.startsWith("v") ? trimmed : `v${trimmed}`;
|
||||
}
|
||||
|
||||
const RENAME_HOST_HEADER: SheetHeader = { title: "Rename host" };
|
||||
const REMOVE_CONNECTION_HEADER: SheetHeader = { title: "Remove connection" };
|
||||
const REMOVE_HOST_HEADER: SheetHeader = { title: "Remove host" };
|
||||
|
||||
export interface HostPageProps {
|
||||
serverId: string;
|
||||
onHostRemoved?: () => void;
|
||||
@@ -244,7 +248,7 @@ export function HostRenameButton({ host }: { host: HostProfile }) {
|
||||
<AdaptiveModalSheet
|
||||
visible={isEditing}
|
||||
onClose={handleCancel}
|
||||
title="Rename host"
|
||||
header={RENAME_HOST_HEADER}
|
||||
testID="host-page-rename-modal"
|
||||
>
|
||||
<View style={styles.renameBody}>
|
||||
@@ -347,7 +351,7 @@ function ConnectionsSection({ host }: { host: HostProfile }) {
|
||||
|
||||
{pendingRemoveConnection ? (
|
||||
<AdaptiveModalSheet
|
||||
title="Remove connection"
|
||||
header={REMOVE_CONNECTION_HEADER}
|
||||
visible
|
||||
onClose={handleCloseConfirm}
|
||||
testID="remove-connection-confirm-modal"
|
||||
@@ -723,7 +727,7 @@ function RemoveHostSection({ host, onRemoved }: { host: HostProfile; onRemoved?:
|
||||
|
||||
{isConfirming ? (
|
||||
<AdaptiveModalSheet
|
||||
title="Remove host"
|
||||
header={REMOVE_HOST_HEADER}
|
||||
visible
|
||||
onClose={handleCloseConfirm}
|
||||
testID="remove-host-confirm-modal"
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { DaemonClient, FetchRecentProviderSessionEntry } from "@server/clie
|
||||
import type { AgentProvider } from "@server/server/agent/agent-sdk-types";
|
||||
import { IMPORTABLE_PROVIDERS } from "@server/shared/importable-providers";
|
||||
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
||||
import { AdaptiveModalSheet } from "@/components/adaptive-modal-sheet";
|
||||
import { AdaptiveModalSheet, type SheetHeader } from "@/components/adaptive-modal-sheet";
|
||||
import { LoadingSpinner } from "@/components/ui/loading-spinner";
|
||||
import { SegmentedControl, type SegmentedControlOption } from "@/components/ui/segmented-control";
|
||||
import { getProviderIcon } from "@/components/provider-icons";
|
||||
@@ -13,6 +13,7 @@ import { formatTimeAgo } from "@/utils/time";
|
||||
import { useProvidersSnapshot } from "@/hooks/use-providers-snapshot";
|
||||
|
||||
const IMPORTABLE_PROVIDER_IDS: Set<string> = new Set(IMPORTABLE_PROVIDERS);
|
||||
const IMPORT_SESSION_HEADER: SheetHeader = { title: "Import session" };
|
||||
const PER_PROVIDER_LIMIT = 15;
|
||||
const IMPORT_SHEET_SNAP_POINTS = ["70%", "92%"];
|
||||
const DISABLED_ACCESSIBILITY_STATE = { disabled: true };
|
||||
@@ -435,7 +436,7 @@ export function WorkspaceImportSheet({
|
||||
<AdaptiveModalSheet
|
||||
visible={visible}
|
||||
onClose={onClose}
|
||||
title="Import session"
|
||||
header={IMPORT_SESSION_HEADER}
|
||||
testID="workspace-import-sheet"
|
||||
desktopMaxWidth={560}
|
||||
snapPoints={IMPORT_SHEET_SNAP_POINTS}
|
||||
|
||||
Reference in New Issue
Block a user