aboutsummaryrefslogtreecommitdiffstats
path: root/apps/web/components/settings/UserOptions.tsx
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2025-05-24 12:59:43 +0000
committerMohamed Bassem <me@mbassem.com>2025-05-24 12:59:43 +0000
commit09652176f97f11bc06f4c9b57a448e14744eac12 (patch)
tree5205f65bdef233328a7b4af010667c5b8c25f285 /apps/web/components/settings/UserOptions.tsx
parent5f3fe5d1a1ad0abd2890283cbff45086cbfa442e (diff)
downloadkarakeep-09652176f97f11bc06f4c9b57a448e14744eac12.tar.zst
feat: Allow defaulting to reader mode when clicking on bookmarks. Fixes #662
Diffstat (limited to 'apps/web/components/settings/UserOptions.tsx')
-rw-r--r--apps/web/components/settings/UserOptions.tsx102
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>
);