feat(app): extract form preferences into dedicated hook with per-provider storage
This commit is contained in:
@@ -119,7 +119,6 @@ export default function HomeScreen() {
|
|||||||
modelError,
|
modelError,
|
||||||
refreshProviderModels,
|
refreshProviderModels,
|
||||||
persistFormPreferences,
|
persistFormPreferences,
|
||||||
userEditedPreferencesRef,
|
|
||||||
} = useAgentFormState({
|
} = useAgentFormState({
|
||||||
initialServerId: resolvedServerId ?? null,
|
initialServerId: resolvedServerId ?? null,
|
||||||
initialValues,
|
initialValues,
|
||||||
@@ -139,11 +138,8 @@ export default function HomeScreen() {
|
|||||||
if (!isValidModel) {
|
if (!isValidModel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (userEditedPreferencesRef.current.model) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setModelFromUser(resolvedModel);
|
setModelFromUser(resolvedModel);
|
||||||
}, [availableModels, resolvedModel, setModelFromUser, userEditedPreferencesRef]);
|
}, [availableModels, resolvedModel, setModelFromUser]);
|
||||||
const hostEntry = selectedServerId
|
const hostEntry = selectedServerId
|
||||||
? connectionStates.get(selectedServerId)
|
? connectionStates.get(selectedServerId)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
||||||
import {
|
import {
|
||||||
AGENT_PROVIDER_DEFINITIONS,
|
AGENT_PROVIDER_DEFINITIONS,
|
||||||
type AgentProviderDefinition,
|
type AgentProviderDefinition,
|
||||||
@@ -13,6 +12,7 @@ import type { WSInboundMessage } from "@server/server/messages";
|
|||||||
import type { ProviderModelState } from "@/stores/session-store";
|
import type { ProviderModelState } from "@/stores/session-store";
|
||||||
import { useSessionStore } from "@/stores/session-store";
|
import { useSessionStore } from "@/stores/session-store";
|
||||||
import { generateMessageId } from "@/types/stream";
|
import { generateMessageId } from "@/types/stream";
|
||||||
|
import { useFormPreferences } from "./use-form-preferences";
|
||||||
|
|
||||||
export type CreateAgentInitialValues = {
|
export type CreateAgentInitialValues = {
|
||||||
workingDir?: string;
|
workingDir?: string;
|
||||||
@@ -42,13 +42,6 @@ type UseAgentFormStateResult = {
|
|||||||
workingDir: string;
|
workingDir: string;
|
||||||
setWorkingDir: (value: string) => void;
|
setWorkingDir: (value: string) => void;
|
||||||
setWorkingDirFromUser: (value: string) => void;
|
setWorkingDirFromUser: (value: string) => void;
|
||||||
userEditedPreferencesRef: React.MutableRefObject<{
|
|
||||||
provider: boolean;
|
|
||||||
mode: boolean;
|
|
||||||
model: boolean;
|
|
||||||
workingDir: boolean;
|
|
||||||
serverId: boolean;
|
|
||||||
}>;
|
|
||||||
providerDefinitions: AgentProviderDefinition[];
|
providerDefinitions: AgentProviderDefinition[];
|
||||||
providerDefinitionMap: Map<AgentProvider, AgentProviderDefinition>;
|
providerDefinitionMap: Map<AgentProvider, AgentProviderDefinition>;
|
||||||
agentDefinition?: AgentProviderDefinition;
|
agentDefinition?: AgentProviderDefinition;
|
||||||
@@ -66,8 +59,6 @@ type UseAgentFormStateResult = {
|
|||||||
persistFormPreferences: () => Promise<void>;
|
persistFormPreferences: () => Promise<void>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const FORM_PREFERENCES_STORAGE_KEY = "@paseo:create-agent-preferences";
|
|
||||||
|
|
||||||
const providerDefinitions = AGENT_PROVIDER_DEFINITIONS;
|
const providerDefinitions = AGENT_PROVIDER_DEFINITIONS;
|
||||||
const providerDefinitionMap = new Map<AgentProvider, AgentProviderDefinition>(
|
const providerDefinitionMap = new Map<AgentProvider, AgentProviderDefinition>(
|
||||||
providerDefinitions.map((definition) => [definition.id, definition])
|
providerDefinitions.map((definition) => [definition.id, definition])
|
||||||
@@ -88,6 +79,14 @@ export function useAgentFormState(
|
|||||||
isTargetDaemonReady = true,
|
isTargetDaemonReady = true,
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
|
const {
|
||||||
|
preferences,
|
||||||
|
isLoading: isPreferencesLoading,
|
||||||
|
getProviderPreferences,
|
||||||
|
updatePreferences,
|
||||||
|
updateProviderPreferences,
|
||||||
|
} = useFormPreferences();
|
||||||
|
|
||||||
const [selectedServerId, setSelectedServerId] = useState<string | null>(
|
const [selectedServerId, setSelectedServerId] = useState<string | null>(
|
||||||
initialServerId
|
initialServerId
|
||||||
);
|
);
|
||||||
@@ -99,14 +98,7 @@ export function useAgentFormState(
|
|||||||
);
|
);
|
||||||
const [selectedModel, setSelectedModel] = useState("");
|
const [selectedModel, setSelectedModel] = useState("");
|
||||||
|
|
||||||
const formPreferencesHydratedRef = useRef(false);
|
const hasHydratedRef = useRef(false);
|
||||||
const userEditedPreferencesRef = useRef({
|
|
||||||
provider: false,
|
|
||||||
mode: false,
|
|
||||||
model: false,
|
|
||||||
workingDir: false,
|
|
||||||
serverId: false,
|
|
||||||
});
|
|
||||||
const hasAppliedInitialValuesRef = useRef(false);
|
const hasAppliedInitialValuesRef = useRef(false);
|
||||||
const providerModelRequestTimersRef = useRef<
|
const providerModelRequestTimersRef = useRef<
|
||||||
Map<string, ReturnType<typeof setTimeout>>
|
Map<string, ReturnType<typeof setTimeout>>
|
||||||
@@ -121,34 +113,52 @@ export function useAgentFormState(
|
|||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
const setSelectedServerIdFromUser = useCallback((value: string | null) => {
|
const setSelectedServerIdFromUser = useCallback(
|
||||||
userEditedPreferencesRef.current.serverId = true;
|
(value: string | null) => {
|
||||||
setSelectedServerId(value);
|
setSelectedServerId(value);
|
||||||
}, []);
|
void updatePreferences({ serverId: value ?? undefined });
|
||||||
|
},
|
||||||
|
[updatePreferences]
|
||||||
|
);
|
||||||
|
|
||||||
const setProviderFromUser = useCallback((provider: AgentProvider) => {
|
const setProviderFromUser = useCallback(
|
||||||
userEditedPreferencesRef.current.provider = true;
|
(provider: AgentProvider) => {
|
||||||
setSelectedProvider(provider);
|
setSelectedProvider(provider);
|
||||||
userEditedPreferencesRef.current.model = true;
|
void updatePreferences({ provider });
|
||||||
setSelectedModel("");
|
|
||||||
userEditedPreferencesRef.current.mode = true;
|
|
||||||
setSelectedMode("");
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const setModeFromUser = useCallback((modeId: string) => {
|
// Restore per-provider preferences if available
|
||||||
userEditedPreferencesRef.current.mode = true;
|
const providerPrefs = getProviderPreferences(provider);
|
||||||
setSelectedMode(modeId);
|
const providerDef = providerDefinitionMap.get(provider);
|
||||||
}, []);
|
|
||||||
|
|
||||||
const setModelFromUser = useCallback((modelId: string) => {
|
setSelectedModel(providerPrefs?.model ?? "");
|
||||||
userEditedPreferencesRef.current.model = true;
|
setSelectedMode(providerPrefs?.mode ?? providerDef?.defaultModeId ?? "");
|
||||||
setSelectedModel(modelId);
|
},
|
||||||
}, []);
|
[getProviderPreferences, updatePreferences]
|
||||||
|
);
|
||||||
|
|
||||||
const setWorkingDirFromUser = useCallback((value: string) => {
|
const setModeFromUser = useCallback(
|
||||||
userEditedPreferencesRef.current.workingDir = true;
|
(modeId: string) => {
|
||||||
setWorkingDir(value);
|
setSelectedMode(modeId);
|
||||||
}, []);
|
void updateProviderPreferences(selectedProvider, { mode: modeId });
|
||||||
|
},
|
||||||
|
[selectedProvider, updateProviderPreferences]
|
||||||
|
);
|
||||||
|
|
||||||
|
const setModelFromUser = useCallback(
|
||||||
|
(modelId: string) => {
|
||||||
|
setSelectedModel(modelId);
|
||||||
|
void updateProviderPreferences(selectedProvider, { model: modelId });
|
||||||
|
},
|
||||||
|
[selectedProvider, updateProviderPreferences]
|
||||||
|
);
|
||||||
|
|
||||||
|
const setWorkingDirFromUser = useCallback(
|
||||||
|
(value: string) => {
|
||||||
|
setWorkingDir(value);
|
||||||
|
void updatePreferences({ workingDir: value });
|
||||||
|
},
|
||||||
|
[updatePreferences]
|
||||||
|
);
|
||||||
|
|
||||||
const applyInitialValues = useCallback(() => {
|
const applyInitialValues = useCallback(() => {
|
||||||
if (!isCreateFlow || !initialValues) {
|
if (!isCreateFlow || !initialValues) {
|
||||||
@@ -156,23 +166,18 @@ export function useAgentFormState(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Object.prototype.hasOwnProperty.call(initialValues, "workingDir")) {
|
if (Object.prototype.hasOwnProperty.call(initialValues, "workingDir")) {
|
||||||
const providedWorkingDir = initialValues.workingDir ?? "";
|
setWorkingDir(initialValues.workingDir ?? "");
|
||||||
userEditedPreferencesRef.current.workingDir = true;
|
|
||||||
setWorkingDir(providedWorkingDir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initialValues.provider && providerDefinitionMap.has(initialValues.provider)) {
|
if (initialValues.provider && providerDefinitionMap.has(initialValues.provider)) {
|
||||||
userEditedPreferencesRef.current.provider = true;
|
|
||||||
setSelectedProvider(initialValues.provider);
|
setSelectedProvider(initialValues.provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof initialValues.modeId === "string" && initialValues.modeId.length > 0) {
|
if (typeof initialValues.modeId === "string" && initialValues.modeId.length > 0) {
|
||||||
userEditedPreferencesRef.current.mode = true;
|
|
||||||
setSelectedMode(initialValues.modeId);
|
setSelectedMode(initialValues.modeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof initialValues.model === "string" && initialValues.model.length > 0) {
|
if (typeof initialValues.model === "string" && initialValues.model.length > 0) {
|
||||||
userEditedPreferencesRef.current.model = true;
|
|
||||||
setSelectedModel(initialValues.model);
|
setSelectedModel(initialValues.model);
|
||||||
}
|
}
|
||||||
}, [initialValues, isCreateFlow]);
|
}, [initialValues, isCreateFlow]);
|
||||||
@@ -199,163 +204,46 @@ export function useAgentFormState(
|
|||||||
});
|
});
|
||||||
}, [requestProviderModels, selectedProvider, workingDir]);
|
}, [requestProviderModels, selectedProvider, workingDir]);
|
||||||
|
|
||||||
|
// Hydrate form state from preferences once loaded
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let isActive = true;
|
if (isPreferencesLoading || hasHydratedRef.current) return;
|
||||||
const hydratePreferences = async () => {
|
hasHydratedRef.current = true;
|
||||||
try {
|
|
||||||
const stored = await AsyncStorage.getItem(FORM_PREFERENCES_STORAGE_KEY);
|
|
||||||
if (!stored || !isActive) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const parsed = JSON.parse(stored) as {
|
|
||||||
workingDir?: string;
|
|
||||||
provider?: AgentProvider;
|
|
||||||
mode?: string;
|
|
||||||
model?: string;
|
|
||||||
serverId?: string;
|
|
||||||
};
|
|
||||||
if (
|
|
||||||
parsed.provider &&
|
|
||||||
providerDefinitionMap.has(parsed.provider) &&
|
|
||||||
!userEditedPreferencesRef.current.provider
|
|
||||||
) {
|
|
||||||
setSelectedProvider(parsed.provider);
|
|
||||||
}
|
|
||||||
if (typeof parsed.mode === "string" && !userEditedPreferencesRef.current.mode) {
|
|
||||||
setSelectedMode(parsed.mode);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
typeof parsed.workingDir === "string" &&
|
|
||||||
!userEditedPreferencesRef.current.workingDir
|
|
||||||
) {
|
|
||||||
setWorkingDir(parsed.workingDir);
|
|
||||||
}
|
|
||||||
if (typeof parsed.model === "string" && !userEditedPreferencesRef.current.model) {
|
|
||||||
setSelectedModel(parsed.model);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
typeof parsed.serverId === "string" &&
|
|
||||||
!userEditedPreferencesRef.current.serverId
|
|
||||||
) {
|
|
||||||
setSelectedServerId(parsed.serverId);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(
|
|
||||||
"[useAgentFormState] Failed to hydrate form preferences:",
|
|
||||||
error
|
|
||||||
);
|
|
||||||
} finally {
|
|
||||||
if (isActive) {
|
|
||||||
formPreferencesHydratedRef.current = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
void hydratePreferences();
|
|
||||||
return () => {
|
|
||||||
isActive = false;
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
const activeProvider =
|
||||||
if (!formPreferencesHydratedRef.current) {
|
preferences.provider &&
|
||||||
return;
|
providerDefinitionMap.has(preferences.provider as AgentProvider)
|
||||||
}
|
? (preferences.provider as AgentProvider)
|
||||||
const persist = async () => {
|
: DEFAULT_PROVIDER;
|
||||||
const nextPayload: {
|
|
||||||
workingDir?: string;
|
const providerPrefs = preferences.providerPreferences?.[activeProvider];
|
||||||
provider?: AgentProvider;
|
const providerDef = providerDefinitionMap.get(activeProvider);
|
||||||
mode?: string;
|
|
||||||
model?: string;
|
setSelectedProvider(activeProvider);
|
||||||
serverId?: string;
|
if (preferences.workingDir) setWorkingDir(preferences.workingDir);
|
||||||
} = {};
|
setSelectedMode(providerPrefs?.mode ?? providerDef?.defaultModeId ?? "");
|
||||||
if (userEditedPreferencesRef.current.workingDir) {
|
if (providerPrefs?.model) setSelectedModel(providerPrefs.model);
|
||||||
nextPayload.workingDir = workingDir;
|
if (preferences.serverId) setSelectedServerId(preferences.serverId);
|
||||||
}
|
}, [isPreferencesLoading, preferences]);
|
||||||
if (userEditedPreferencesRef.current.provider) {
|
|
||||||
nextPayload.provider = selectedProvider;
|
|
||||||
}
|
|
||||||
if (userEditedPreferencesRef.current.mode) {
|
|
||||||
nextPayload.mode = selectedMode;
|
|
||||||
}
|
|
||||||
if (userEditedPreferencesRef.current.model) {
|
|
||||||
nextPayload.model = selectedModel;
|
|
||||||
}
|
|
||||||
if (userEditedPreferencesRef.current.serverId) {
|
|
||||||
nextPayload.serverId = selectedServerId ?? undefined;
|
|
||||||
}
|
|
||||||
if (Object.keys(nextPayload).length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
const stored = await AsyncStorage.getItem(FORM_PREFERENCES_STORAGE_KEY);
|
|
||||||
const parsed = stored
|
|
||||||
? (JSON.parse(stored) as Record<string, unknown>)
|
|
||||||
: {};
|
|
||||||
await AsyncStorage.setItem(
|
|
||||||
FORM_PREFERENCES_STORAGE_KEY,
|
|
||||||
JSON.stringify({
|
|
||||||
...parsed,
|
|
||||||
...nextPayload,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(
|
|
||||||
"[useAgentFormState] Failed to persist form preferences:",
|
|
||||||
error
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
void persist();
|
|
||||||
}, [selectedMode, selectedProvider, workingDir, selectedModel, selectedServerId]);
|
|
||||||
|
|
||||||
const persistFormPreferences = useCallback(async () => {
|
const persistFormPreferences = useCallback(async () => {
|
||||||
const payload: {
|
await updatePreferences({
|
||||||
workingDir?: string;
|
workingDir,
|
||||||
provider?: AgentProvider;
|
provider: selectedProvider,
|
||||||
mode?: string;
|
serverId: selectedServerId ?? undefined,
|
||||||
model?: string;
|
});
|
||||||
serverId?: string;
|
await updateProviderPreferences(selectedProvider, {
|
||||||
} = {};
|
mode: selectedMode,
|
||||||
|
model: selectedModel,
|
||||||
if (typeof workingDir === "string") {
|
});
|
||||||
payload.workingDir = workingDir;
|
}, [
|
||||||
}
|
selectedMode,
|
||||||
if (selectedProvider) {
|
selectedModel,
|
||||||
payload.provider = selectedProvider;
|
selectedProvider,
|
||||||
}
|
selectedServerId,
|
||||||
if (typeof selectedMode === "string") {
|
workingDir,
|
||||||
payload.mode = selectedMode;
|
updatePreferences,
|
||||||
}
|
updateProviderPreferences,
|
||||||
if (typeof selectedModel === "string") {
|
]);
|
||||||
payload.model = selectedModel;
|
|
||||||
}
|
|
||||||
if (selectedServerId) {
|
|
||||||
payload.serverId = selectedServerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Object.keys(payload).length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const stored = await AsyncStorage.getItem(FORM_PREFERENCES_STORAGE_KEY);
|
|
||||||
const parsed = stored
|
|
||||||
? (JSON.parse(stored) as Record<string, unknown>)
|
|
||||||
: {};
|
|
||||||
await AsyncStorage.setItem(
|
|
||||||
FORM_PREFERENCES_STORAGE_KEY,
|
|
||||||
JSON.stringify({
|
|
||||||
...parsed,
|
|
||||||
...payload,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(
|
|
||||||
"[useAgentFormState] Failed to persist form preferences:",
|
|
||||||
error
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [selectedMode, selectedModel, selectedProvider, selectedServerId, workingDir]);
|
|
||||||
|
|
||||||
const clearQueuedProviderModelRequest = useCallback((serverId: string | null) => {
|
const clearQueuedProviderModelRequest = useCallback((serverId: string | null) => {
|
||||||
if (!serverId) {
|
if (!serverId) {
|
||||||
@@ -489,7 +377,6 @@ export function useAgentFormState(
|
|||||||
workingDir,
|
workingDir,
|
||||||
setWorkingDir,
|
setWorkingDir,
|
||||||
setWorkingDirFromUser,
|
setWorkingDirFromUser,
|
||||||
userEditedPreferencesRef,
|
|
||||||
providerDefinitions,
|
providerDefinitions,
|
||||||
providerDefinitionMap,
|
providerDefinitionMap,
|
||||||
agentDefinition,
|
agentDefinition,
|
||||||
@@ -520,6 +407,7 @@ export function useAgentFormState(
|
|||||||
setProviderFromUser,
|
setProviderFromUser,
|
||||||
setModeFromUser,
|
setModeFromUser,
|
||||||
setModelFromUser,
|
setModelFromUser,
|
||||||
|
setWorkingDirFromUser,
|
||||||
workingDir,
|
workingDir,
|
||||||
workingDirIsEmpty,
|
workingDirIsEmpty,
|
||||||
persistFormPreferences,
|
persistFormPreferences,
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
import { useCallback } from "react";
|
||||||
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||||
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
|
import { z } from "zod";
|
||||||
|
import type { AgentProvider } from "@server/server/agent/agent-sdk-types";
|
||||||
|
|
||||||
|
const FORM_PREFERENCES_STORAGE_KEY = "@paseo:create-agent-preferences";
|
||||||
|
const FORM_PREFERENCES_QUERY_KEY = ["form-preferences"];
|
||||||
|
|
||||||
|
const providerPreferencesSchema = z.object({
|
||||||
|
model: z.string().optional(),
|
||||||
|
mode: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const formPreferencesSchema = z.object({
|
||||||
|
workingDir: z.string().optional(),
|
||||||
|
provider: z.string().optional(),
|
||||||
|
serverId: z.string().optional(),
|
||||||
|
providerPreferences: z.record(providerPreferencesSchema).optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type ProviderPreferences = z.infer<typeof providerPreferencesSchema>;
|
||||||
|
export type FormPreferences = z.infer<typeof formPreferencesSchema>;
|
||||||
|
|
||||||
|
const DEFAULT_FORM_PREFERENCES: FormPreferences = {};
|
||||||
|
|
||||||
|
async function loadFormPreferences(): Promise<FormPreferences> {
|
||||||
|
const stored = await AsyncStorage.getItem(FORM_PREFERENCES_STORAGE_KEY);
|
||||||
|
if (!stored) return DEFAULT_FORM_PREFERENCES;
|
||||||
|
const result = formPreferencesSchema.safeParse(JSON.parse(stored));
|
||||||
|
return result.success ? result.data : DEFAULT_FORM_PREFERENCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UseFormPreferencesReturn {
|
||||||
|
preferences: FormPreferences;
|
||||||
|
isLoading: boolean;
|
||||||
|
getProviderPreferences: (provider: AgentProvider) => ProviderPreferences | undefined;
|
||||||
|
updatePreferences: (updates: Partial<FormPreferences>) => Promise<void>;
|
||||||
|
updateProviderPreferences: (
|
||||||
|
provider: AgentProvider,
|
||||||
|
updates: Partial<ProviderPreferences>
|
||||||
|
) => Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useFormPreferences(): UseFormPreferencesReturn {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
const { data, isPending } = useQuery({
|
||||||
|
queryKey: FORM_PREFERENCES_QUERY_KEY,
|
||||||
|
queryFn: loadFormPreferences,
|
||||||
|
staleTime: Infinity,
|
||||||
|
gcTime: Infinity,
|
||||||
|
});
|
||||||
|
|
||||||
|
const preferences = data ?? DEFAULT_FORM_PREFERENCES;
|
||||||
|
|
||||||
|
const getProviderPreferences = useCallback(
|
||||||
|
(provider: AgentProvider): ProviderPreferences | undefined => {
|
||||||
|
return preferences.providerPreferences?.[provider];
|
||||||
|
},
|
||||||
|
[preferences.providerPreferences]
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatePreferences = useCallback(
|
||||||
|
async (updates: Partial<FormPreferences>) => {
|
||||||
|
const prev =
|
||||||
|
queryClient.getQueryData<FormPreferences>(FORM_PREFERENCES_QUERY_KEY) ??
|
||||||
|
DEFAULT_FORM_PREFERENCES;
|
||||||
|
const next = { ...prev, ...updates };
|
||||||
|
queryClient.setQueryData<FormPreferences>(FORM_PREFERENCES_QUERY_KEY, next);
|
||||||
|
await AsyncStorage.setItem(FORM_PREFERENCES_STORAGE_KEY, JSON.stringify(next));
|
||||||
|
},
|
||||||
|
[queryClient]
|
||||||
|
);
|
||||||
|
|
||||||
|
const updateProviderPreferences = useCallback(
|
||||||
|
async (provider: AgentProvider, updates: Partial<ProviderPreferences>) => {
|
||||||
|
const prev =
|
||||||
|
queryClient.getQueryData<FormPreferences>(FORM_PREFERENCES_QUERY_KEY) ??
|
||||||
|
DEFAULT_FORM_PREFERENCES;
|
||||||
|
const next: FormPreferences = {
|
||||||
|
...prev,
|
||||||
|
providerPreferences: {
|
||||||
|
...prev.providerPreferences,
|
||||||
|
[provider]: {
|
||||||
|
...prev.providerPreferences?.[provider],
|
||||||
|
...updates,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
queryClient.setQueryData<FormPreferences>(FORM_PREFERENCES_QUERY_KEY, next);
|
||||||
|
await AsyncStorage.setItem(FORM_PREFERENCES_STORAGE_KEY, JSON.stringify(next));
|
||||||
|
},
|
||||||
|
[queryClient]
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
preferences,
|
||||||
|
isLoading: isPending,
|
||||||
|
getProviderPreferences,
|
||||||
|
updatePreferences,
|
||||||
|
updateProviderPreferences,
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user