Skip to content

Commit 482a094

Browse files
authored
Small UX updates assistants (#872)
1 parent 264c8d0 commit 482a094

File tree

4 files changed

+73
-6
lines changed

4 files changed

+73
-6
lines changed

src/lib/stores/settings.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ type SettingsStore = {
1717
assistants: Array<ObjectId | string>;
1818
};
1919

20+
type SettingsStoreWritable = Writable<SettingsStore> & {
21+
instantSet: (settings: Partial<SettingsStore>) => Promise<void>;
22+
};
23+
2024
export function useSettingsStore() {
21-
return getContext<Writable<SettingsStore>>("settings");
25+
return getContext<SettingsStoreWritable>("settings");
2226
}
2327

2428
export function createSettingsStore(initialValue: Omit<SettingsStore, "recentlySaved">) {
@@ -64,14 +68,35 @@ export function createSettingsStore(initialValue: Omit<SettingsStore, "recentlyS
6468
// debounce server calls by 300ms
6569
}
6670
}
71+
async function instantSet(settings: Partial<SettingsStore>) {
72+
baseStore.update((s) => ({
73+
...s,
74+
...settings,
75+
}));
76+
77+
if (browser) {
78+
await fetch(`${base}/settings`, {
79+
method: "POST",
80+
headers: {
81+
"Content-Type": "application/json",
82+
},
83+
body: JSON.stringify({
84+
...get(baseStore),
85+
...settings,
86+
}),
87+
});
88+
invalidate(UrlDependency.ConversationList);
89+
}
90+
}
6791

6892
const newStore = {
6993
subscribe: baseStore.subscribe,
7094
set: setSettings,
95+
instantSet,
7196
update: (fn: (s: SettingsStore) => SettingsStore) => {
7297
setSettings(fn(get(baseStore)));
7398
},
74-
} satisfies Writable<SettingsStore>;
99+
} satisfies SettingsStoreWritable;
75100

76101
setContext("settings", newStore);
77102

src/routes/+layout.svelte

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@
116116
if ($settings.activeModel === $page.url.searchParams.get("model")) {
117117
goto(`${base}/?`);
118118
}
119-
$settings.activeModel = $page.url.searchParams.get("model") ?? $settings.activeModel;
119+
settings.instantSet({
120+
activeModel: $page.url.searchParams.get("model") ?? $settings.activeModel,
121+
});
120122
}
121123
122124
$: mobileNavTitle = ["/models", "/assistants", "/privacy"].includes($page.route.id ?? "")

src/routes/assistant/[assistantId]/+page.svelte

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import { applyAction, enhance } from "$app/forms";
99
import { PUBLIC_APP_NAME, PUBLIC_ORIGIN } from "$env/static/public";
1010
import { page } from "$app/stores";
11+
import IconGear from "~icons/bi/gear-fill";
1112
1213
export let data: PageData;
1314
@@ -47,6 +48,35 @@
4748
}}
4849
class="z-10 flex flex-col content-center items-center gap-x-10 gap-y-3 overflow-hidden rounded-2xl bg-white p-4 pt-6 text-center shadow-2xl outline-none max-sm:w-[85dvw] max-sm:px-6 md:w-96 md:grid-cols-3 md:grid-rows-[auto,1fr] md:p-8"
4950
>
51+
<div class="absolute right-0 top-0 m-6">
52+
<form
53+
method="POST"
54+
action="{base}/settings/assistants/{data.assistant._id}?/subscribe"
55+
class="w-full"
56+
use:enhance={() => {
57+
return async ({ result }) => {
58+
// `result` is an `ActionResult` object
59+
if (result.type === "success") {
60+
$settings.activeModel = data.assistant._id;
61+
await goto(`${base}/settings/assistants/${data.assistant._id}`, {
62+
invalidateAll: true,
63+
});
64+
} else {
65+
await applyAction(result);
66+
}
67+
};
68+
}}
69+
>
70+
<button
71+
class="flex items-center rounded-full border border-gray-200 px-2.5 py-1 text-sm text-gray-900 hover:bg-gray-100"
72+
name="Settings"
73+
type="submit"
74+
>
75+
<IconGear class="mr-1.5 text-xxs" />
76+
Settings
77+
</button>
78+
</form>
79+
</div>
5080
{#if data.assistant.avatar}
5181
<img
5282
class="size-16 flex-none rounded-full object-cover sm:size-24"

src/routes/assistants/+page.svelte

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import Pagination from "$lib/components/Pagination.svelte";
1818
import { formatUserCount } from "$lib/utils/formatUserCount";
1919
import { getHref } from "$lib/utils/getHref";
20+
import { useSettingsStore } from "$lib/stores/settings";
2021
2122
export let data: PageData;
2223
@@ -30,6 +31,8 @@
3031
});
3132
goto(newUrl);
3233
};
34+
35+
const settings = useSettingsStore();
3336
</script>
3437

3538
<svelte:head>
@@ -143,9 +146,16 @@
143146

144147
<div class="mt-8 grid grid-cols-2 gap-3 sm:gap-5 md:grid-cols-3 lg:grid-cols-4">
145148
{#each data.assistants as assistant (assistant._id)}
146-
<a
147-
href="{base}/assistant/{assistant._id}"
149+
<button
148150
class="relative flex flex-col items-center justify-center overflow-hidden text-balance rounded-xl border bg-gray-50/50 px-4 py-6 text-center shadow hover:bg-gray-50 hover:shadow-inner max-sm:px-4 sm:h-64 sm:pb-4 xl:pt-8 dark:border-gray-800/70 dark:bg-gray-950/20 dark:hover:bg-gray-950/40"
151+
on:click={() => {
152+
if (data.settings.assistants.includes(assistant._id.toString())) {
153+
settings.instantSet({ activeModel: assistant._id.toString() });
154+
goto(`${base}` || "/");
155+
} else {
156+
goto(`${base}/assistant/${assistant._id}`);
157+
}
158+
}}
149159
>
150160
{#if assistant.userCount && assistant.userCount > 1}
151161
<div
@@ -186,7 +196,7 @@
186196
</a>
187197
</p>
188198
{/if}
189-
</a>
199+
</button>
190200
{:else}
191201
No assistants found
192202
{/each}

0 commit comments

Comments
 (0)