aboutsummaryrefslogtreecommitdiffstats
path: root/packages/trpc/routers
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 /packages/trpc/routers
parent5f3fe5d1a1ad0abd2890283cbff45086cbfa442e (diff)
downloadkarakeep-09652176f97f11bc06f4c9b57a448e14744eac12.tar.zst
feat: Allow defaulting to reader mode when clicking on bookmarks. Fixes #662
Diffstat (limited to 'packages/trpc/routers')
-rw-r--r--packages/trpc/routers/users.test.ts35
-rw-r--r--packages/trpc/routers/users.ts41
2 files changed, 76 insertions, 0 deletions
diff --git a/packages/trpc/routers/users.test.ts b/packages/trpc/routers/users.test.ts
index ea342d33..3d2d164d 100644
--- a/packages/trpc/routers/users.test.ts
+++ b/packages/trpc/routers/users.test.ts
@@ -94,4 +94,39 @@ describe("User Routes", () => {
// A normal user can't list all users
await expect(() => user2Caller.users.list()).rejects.toThrow(/FORBIDDEN/);
});
+
+ test<CustomTestContext>("get/update user settings", async ({
+ db,
+ unauthedAPICaller,
+ }) => {
+ const user = await unauthedAPICaller.users.create({
+ name: "Test User",
+ email: "testupdate@test.com",
+ password: "pass1234",
+ confirmPassword: "pass1234",
+ });
+ const caller = getApiCaller(db, user.id);
+
+ const settings = await caller.users.settings();
+ // The default settings
+ expect(settings).toEqual({
+ bookmarkClickAction: "open_original_link",
+ });
+
+ // Update settings
+ await caller.users.updateSettings({
+ bookmarkClickAction: "expand_bookmark_preview",
+ });
+
+ // Verify updated settings
+ const updatedSettings = await caller.users.settings();
+ expect(updatedSettings).toEqual({
+ bookmarkClickAction: "expand_bookmark_preview",
+ });
+
+ // Test invalid update (e.g., empty input, if schema enforces it)
+ await expect(() => caller.users.updateSettings({})).rejects.toThrow(
+ /No settings provided/,
+ );
+ });
});
diff --git a/packages/trpc/routers/users.ts b/packages/trpc/routers/users.ts
index c56daaee..6f1f1145 100644
--- a/packages/trpc/routers/users.ts
+++ b/packages/trpc/routers/users.ts
@@ -10,11 +10,14 @@ import {
bookmarkTags,
highlights,
users,
+ userSettings,
} from "@karakeep/db/schema";
import { deleteUserAssets } from "@karakeep/shared/assetdb";
import serverConfig from "@karakeep/shared/config";
import {
zSignUpSchema,
+ zUpdateUserSettingsSchema,
+ zUserSettingsSchema,
zUserStatsResponseSchema,
zWhoAmIResponseSchema,
} from "@karakeep/shared/types/users";
@@ -59,6 +62,12 @@ export async function createUser(
email: users.email,
role: users.role,
});
+
+ // Insert user settings for the new user
+ await trx.insert(userSettings).values({
+ userId: result[0].id,
+ });
+
return result[0];
} catch (e) {
if (e instanceof SqliteError) {
@@ -242,4 +251,36 @@ export const usersAppRouter = router({
numHighlights,
};
}),
+ settings: authedProcedure
+ .output(zUserSettingsSchema)
+ .query(async ({ ctx }) => {
+ const settings = await ctx.db.query.userSettings.findFirst({
+ where: eq(userSettings.userId, ctx.user.id),
+ });
+ if (!settings) {
+ throw new TRPCError({
+ code: "NOT_FOUND",
+ message: "User settings not found",
+ });
+ }
+ return {
+ bookmarkClickAction: settings.bookmarkClickAction,
+ };
+ }),
+ updateSettings: authedProcedure
+ .input(zUpdateUserSettingsSchema)
+ .mutation(async ({ input, ctx }) => {
+ if (Object.keys(input).length === 0) {
+ throw new TRPCError({
+ code: "BAD_REQUEST",
+ message: "No settings provided",
+ });
+ }
+ await ctx.db
+ .update(userSettings)
+ .set({
+ bookmarkClickAction: input.bookmarkClickAction,
+ })
+ .where(eq(userSettings.userId, ctx.user.id));
+ }),
});