diff options
| author | Mohamed Bassem <me@mbassem.com> | 2025-05-24 12:59:43 +0000 |
|---|---|---|
| committer | Mohamed Bassem <me@mbassem.com> | 2025-05-24 12:59:43 +0000 |
| commit | 09652176f97f11bc06f4c9b57a448e14744eac12 (patch) | |
| tree | 5205f65bdef233328a7b4af010667c5b8c25f285 /apps/web/components/settings | |
| parent | 5f3fe5d1a1ad0abd2890283cbff45086cbfa442e (diff) | |
| download | karakeep-09652176f97f11bc06f4c9b57a448e14744eac12.tar.zst | |
feat: Allow defaulting to reader mode when clicking on bookmarks. Fixes #662
Diffstat (limited to 'apps/web/components/settings')
| -rw-r--r-- | apps/web/components/settings/UserOptions.tsx | 102 |
1 files changed, 99 insertions, 3 deletions
diff --git a/apps/web/components/settings/UserOptions.tsx b/apps/web/components/settings/UserOptions.tsx index 33ffc46a..c8aa5e86 100644 --- a/apps/web/components/settings/UserOptions.tsx +++ b/apps/web/components/settings/UserOptions.tsx @@ -1,11 +1,23 @@ "use client"; +import { useEffect } from "react"; +import { useClientConfig } from "@/lib/clientConfig"; import { useTranslation } from "@/lib/i18n/client"; import { useInterfaceLang } from "@/lib/userLocalSettings/bookmarksLayout"; import { updateInterfaceLang } from "@/lib/userLocalSettings/userLocalSettings"; +import { useUserSettings } from "@/lib/userSettings"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { useUpdateUserSettings } from "@karakeep/shared-react/hooks/users"; import { langNameMappings } from "@karakeep/shared/langs"; +import { + ZUserSettings, + zUserSettingsSchema, +} from "@karakeep/shared/types/users"; +import { Form, FormField } from "../ui/form"; import { Label } from "../ui/label"; import { Select, @@ -14,6 +26,7 @@ import { SelectTrigger, SelectValue, } from "../ui/select"; +import { toast } from "../ui/use-toast"; const LanguageSelect = () => { const lang = useInterfaceLang(); @@ -38,6 +51,86 @@ const LanguageSelect = () => { ); }; +export default function UserSettings() { + const { t } = useTranslation(); + const clientConfig = useClientConfig(); + const data = useUserSettings(); + const { mutate } = useUpdateUserSettings({ + onSuccess: () => { + toast({ + description: t("settings.info.user_settings.user_settings_updated"), + }); + }, + onError: () => { + toast({ + description: t("common.something_went_wrong"), + variant: "destructive", + }); + }, + }); + + const bookmarkClickActionTranslation: Record< + ZUserSettings["bookmarkClickAction"], + string + > = { + open_original_link: t("settings.info.user_settings.open_external_url"), + expand_bookmark_preview: t( + "settings.info.user_settings.open_bookmark_details", + ), + }; + + const form = useForm<z.infer<typeof zUserSettingsSchema>>({ + resolver: zodResolver(zUserSettingsSchema), + defaultValues: data, + }); + + // When the actual user setting is loaded, reset the form to the current value + useEffect(() => { + form.reset(data); + }, [data]); + + return ( + <Form {...form}> + <FormField + control={form.control} + name="bookmarkClickAction" + render={({ field }) => ( + <div className="flex w-full flex-col gap-2"> + <Label> + {t("settings.info.user_settings.boomark_click_action")} + </Label> + <Select + disabled={!!clientConfig.demoMode} + value={field.value} + onValueChange={(value) => { + mutate({ + bookmarkClickAction: + value as ZUserSettings["bookmarkClickAction"], + }); + }} + > + <SelectTrigger> + <SelectValue> + {bookmarkClickActionTranslation[field.value]} + </SelectValue> + </SelectTrigger> + <SelectContent> + {Object.entries(bookmarkClickActionTranslation).map( + ([value, label]) => ( + <SelectItem key={value} value={value}> + {label} + </SelectItem> + ), + )} + </SelectContent> + </Select> + </div> + )} + /> + </Form> + ); +} + export function UserOptions() { const { t } = useTranslation(); @@ -46,9 +139,12 @@ export function UserOptions() { <div className="mb-4 w-full text-lg font-medium sm:w-1/3"> {t("settings.info.options")} </div> - <div className="flex w-full flex-col gap-2"> - <Label>{t("settings.info.interface_lang")}</Label> - <LanguageSelect /> + <div className="flex w-full flex-col gap-3"> + <div className="flex w-full flex-col gap-2"> + <Label>{t("settings.info.interface_lang")}</Label> + <LanguageSelect /> + </div> + <UserSettings /> </div> </div> ); |
