Skip to content

Commit

Permalink
Refactor settings migration logic
Browse files Browse the repository at this point in the history
  • Loading branch information
amanape committed Dec 30, 2024
1 parent 59210ef commit 9dfc732
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 53 deletions.
2 changes: 2 additions & 0 deletions frontend/src/components/features/sidebar/sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ export function Sidebar() {
const { logout } = useAuth();
const { isUpToDate: settingsAreUpToDate } = useSettingsUpToDate();

console.warn({ settingsAreUpToDate });

const [accountSettingsModalOpen, setAccountSettingsModalOpen] =
React.useState(false);
const [settingsModalIsOpen, setSettingsModalIsOpen] = React.useState(false);
Expand Down
20 changes: 13 additions & 7 deletions frontend/src/hooks/mutation/use-save-settings.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { ApiSettings, Settings } from "#/services/settings";
import {
ApiSettings,
LATEST_SETTINGS_VERSION,
Settings,
} from "#/services/settings";
import OpenHands from "#/api/open-hands";
import { updateSettingsVersion } from "#/utils/settings-utils";
import { useAuth } from "#/context/auth-context";
import { useSettingsUpToDate } from "#/context/settings-up-to-date-context";

const saveSettingsMutationFn = async (settings: Partial<Settings>) => {
Expand All @@ -21,15 +23,19 @@ const saveSettingsMutationFn = async (settings: Partial<Settings>) => {

export const useSaveSettings = () => {
const queryClient = useQueryClient();
const { logout } = useAuth();
const { setIsUpToDate } = useSettingsUpToDate();
const { isUpToDate, setIsUpToDate } = useSettingsUpToDate();

return useMutation({
mutationFn: saveSettingsMutationFn,
onSuccess: async () => {
await queryClient.invalidateQueries({ queryKey: ["settings"] });
updateSettingsVersion(logout);
setIsUpToDate(true);
if (!isUpToDate) {
localStorage.setItem(
"SETTINGS_VERSION",
LATEST_SETTINGS_VERSION.toString(),
);
setIsUpToDate(true);
}
},
});
};
54 changes: 54 additions & 0 deletions frontend/src/hooks/use-maybe-migrate-settings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Sometimes we ship major changes, like a new default agent.

import React from "react";
import { useAuth } from "#/context/auth-context";
import { useSettingsUpToDate } from "#/context/settings-up-to-date-context";
import {
DEFAULT_SETTINGS,
getCurrentSettingsVersion,
getLocalStorageSettings,
} from "#/services/settings";
import { useSaveSettings } from "./mutation/use-save-settings";

// In this case, we may want to override a previous choice made by the user.
export const useMaybeMigrateSettings = () => {
const { logout } = useAuth();
const { mutateAsync: saveSettings } = useSaveSettings();
const { isUpToDate } = useSettingsUpToDate();

const maybeMigrateSettings = async () => {
const currentVersion = getCurrentSettingsVersion();

if (currentVersion < 1) {
localStorage.setItem("AGENT", DEFAULT_SETTINGS.AGENT);
}
if (currentVersion < 2) {
const customModel = localStorage.getItem("CUSTOM_LLM_MODEL");
if (customModel) {
localStorage.setItem("LLM_MODEL", customModel);
}
localStorage.removeItem("CUSTOM_LLM_MODEL");
localStorage.removeItem("USING_CUSTOM_MODEL");
}
if (currentVersion < 3) {
localStorage.removeItem("token");
}

if (currentVersion < 4) {
logout();
}

// Only save settings if user already previously saved settings
// That way we avoid setting defaults for new users too early
if (currentVersion !== 0 && currentVersion < 5) {
const localSettings = getLocalStorageSettings();
await saveSettings(localSettings);
}
};

React.useEffect(() => {
if (!isUpToDate) {
maybeMigrateSettings();
}
}, []);
};
3 changes: 3 additions & 0 deletions frontend/src/routes/_oh/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Sidebar } from "#/components/features/sidebar/sidebar";
import { WaitlistModal } from "#/components/features/waitlist/waitlist-modal";
import { AnalyticsConsentFormModal } from "#/components/features/analytics/analytics-consent-form-modal";
import { useSettings } from "#/hooks/query/use-settings";
import { useMaybeMigrateSettings } from "#/hooks/use-maybe-migrate-settings";

export function ErrorBoundary() {
const error = useRouteError();
Expand Down Expand Up @@ -43,6 +44,8 @@ export function ErrorBoundary() {
}

export default function MainApp() {
useMaybeMigrateSettings();

const { gitHubToken } = useAuth();
const { data: settings } = useSettings();

Expand Down
25 changes: 0 additions & 25 deletions frontend/src/services/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,6 @@ export const getLocalStorageSettings = (): Settings => {
};
};

export const maybeMigrateSettings = async (logout: () => void) => {
// Sometimes we ship major changes, like a new default agent.
// In this case, we may want to override a previous choice made by the user.
const currentVersion = getCurrentSettingsVersion();

if (currentVersion < 1) {
localStorage.setItem("AGENT", DEFAULT_SETTINGS.AGENT);
}
if (currentVersion < 2) {
const customModel = localStorage.getItem("CUSTOM_LLM_MODEL");
if (customModel) {
localStorage.setItem("LLM_MODEL", customModel);
}
localStorage.removeItem("CUSTOM_LLM_MODEL");
localStorage.removeItem("USING_CUSTOM_MODEL");
}
if (currentVersion < 3) {
localStorage.removeItem("token");
}

if (currentVersion < 4) {
logout();
}
};

/**
* Get the default settings
*/
Expand Down
23 changes: 2 additions & 21 deletions frontend/src/utils/settings-utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import {
settingsAreUpToDate,
maybeMigrateSettings,
LATEST_SETTINGS_VERSION,
Settings,
} from "#/services/settings";
import { Settings } from "#/services/settings";

const extractBasicFormData = (formData: FormData) => {
const provider = formData.get("llm-provider")?.toString();
Expand Down Expand Up @@ -78,18 +73,4 @@ const saveSettingsView = (view: "basic" | "advanced") => {
);
};

/**
* Updates the settings version in local storage if the current settings are not up to date.
* If the settings are outdated, it attempts to migrate them before updating the version.
*/
const updateSettingsVersion = async (logout: () => void) => {
if (!settingsAreUpToDate()) {
await maybeMigrateSettings(logout);
localStorage.setItem(
"SETTINGS_VERSION",
LATEST_SETTINGS_VERSION.toString(),
);
}
};

export { extractSettings, saveSettingsView, updateSettingsVersion };
export { extractSettings, saveSettingsView };

0 comments on commit 9dfc732

Please sign in to comment.