toggle public private and protect messages (#25)
This commit is contained in:
parent
f778dbd9ec
commit
f5efc2490a
4 changed files with 57 additions and 23 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { v } from 'convex/values';
|
||||
import enhancedSearch, { type SearchResult } from '../../utils/fuzzy-search';
|
||||
import enhancedSearch from '../../utils/fuzzy-search';
|
||||
import { getFirstSentence } from '../../utils/strings';
|
||||
import { api } from './_generated/api';
|
||||
import { type Doc, type Id } from './_generated/dataModel';
|
||||
|
|
@ -54,7 +54,7 @@ export const getById = query({
|
|||
|
||||
const conversation = await ctx.db.get(args.conversation_id);
|
||||
|
||||
if (!conversation || (conversation.user_id !== session.userId && !conversation.public)) {
|
||||
if (!conversation || (!conversation.public && conversation.user_id !== session.userId)) {
|
||||
throw new Error('Conversation not found or unauthorized');
|
||||
}
|
||||
|
||||
|
|
@ -227,9 +227,10 @@ export const updateCostUsd = mutation({
|
|||
},
|
||||
});
|
||||
|
||||
export const makePublic = mutation({
|
||||
export const setPublic = mutation({
|
||||
args: {
|
||||
conversation_id: v.id('conversations'),
|
||||
public: v.boolean(),
|
||||
session_token: v.string(),
|
||||
},
|
||||
handler: async (ctx, args) => {
|
||||
|
|
@ -245,7 +246,7 @@ export const makePublic = mutation({
|
|||
}
|
||||
|
||||
await ctx.db.patch(args.conversation_id, {
|
||||
public: true,
|
||||
public: args.public,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,16 +15,21 @@ export const getAllFromConversation = query({
|
|||
session_token: args.session_token,
|
||||
});
|
||||
|
||||
if (!session) {
|
||||
if (!session) throw new Error('Unauthorized');
|
||||
|
||||
const [messages, conversation] = await Promise.all([
|
||||
ctx.db
|
||||
.query('messages')
|
||||
.withIndex('by_conversation', (q) => q.eq('conversation_id', args.conversation_id))
|
||||
.order('asc')
|
||||
.collect(),
|
||||
ctx.db.get(args.conversation_id as Id<'conversations'>),
|
||||
]);
|
||||
|
||||
if (!conversation?.public && conversation?.user_id !== session.userId) {
|
||||
throw new Error('Unauthorized');
|
||||
}
|
||||
|
||||
const messages = await ctx.db
|
||||
.query('messages')
|
||||
.withIndex('by_conversation', (q) => q.eq('conversation_id', args.conversation_id))
|
||||
.order('asc')
|
||||
.collect();
|
||||
|
||||
return messages;
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -362,8 +362,9 @@
|
|||
if (!page.params.id || !session.current?.session.token) return;
|
||||
|
||||
const result = await ResultAsync.fromPromise(
|
||||
client.mutation(api.conversations.makePublic, {
|
||||
client.mutation(api.conversations.setPublic, {
|
||||
conversation_id: page.params.id as Id<'conversations'>,
|
||||
public: true,
|
||||
session_token: session.current?.session.token ?? '',
|
||||
}),
|
||||
(e) => e
|
||||
|
|
@ -379,6 +380,19 @@
|
|||
clipboard.copy(page.url.toString());
|
||||
}
|
||||
|
||||
async function togglePublic() {
|
||||
if (!page.params.id || !session.current?.session.token) return;
|
||||
|
||||
await ResultAsync.fromPromise(
|
||||
client.mutation(api.conversations.setPublic, {
|
||||
conversation_id: page.params.id as Id<'conversations'>,
|
||||
public: !currentConversationQuery.data?.public,
|
||||
session_token: session.current?.session.token ?? '',
|
||||
}),
|
||||
(e) => e
|
||||
);
|
||||
}
|
||||
|
||||
const textareaSize = new ElementSize(() => textarea);
|
||||
|
||||
let textareaWrapper = $state<HTMLDivElement>();
|
||||
|
|
@ -451,11 +465,14 @@
|
|||
Toggle Sidebar ({cmdOrCtrl} + B)
|
||||
</Tooltip>
|
||||
|
||||
{#if page.params.id}
|
||||
{#if page.params.id && currentConversationQuery.data}
|
||||
<Tooltip>
|
||||
{#snippet trigger(tooltip)}
|
||||
<div
|
||||
class="z-50 flex size-8 items-center justify-center md:top-1 md:left-auto"
|
||||
<Button
|
||||
class="bg-sidebar size-8"
|
||||
size="icon"
|
||||
variant="ghost"
|
||||
onClickPromise={togglePublic}
|
||||
{...tooltip.trigger}
|
||||
>
|
||||
{#if currentConversationQuery.data?.public}
|
||||
|
|
@ -463,7 +480,7 @@
|
|||
{:else}
|
||||
<LockIcon class="size-4" />
|
||||
{/if}
|
||||
</div>
|
||||
</Button>
|
||||
{/snippet}
|
||||
{currentConversationQuery.data?.public ? 'Public' : 'Private'}
|
||||
</Tooltip>
|
||||
|
|
@ -477,7 +494,7 @@
|
|||
{ 'hidden md:flex': sidebarOpen }
|
||||
)}
|
||||
>
|
||||
{#if page.params.id}
|
||||
{#if page.params.id && currentConversationQuery.data}
|
||||
<Tooltip>
|
||||
{#snippet trigger(tooltip)}
|
||||
<Button
|
||||
|
|
@ -761,7 +778,7 @@
|
|||
</div>
|
||||
|
||||
<!-- Credits in bottom-right, only on large screens -->
|
||||
<div class="fixed right-4 bottom-4 hidden flex-col items-end gap-1 xl:flex">
|
||||
<div class="fixed right-4 bottom-4 hidden flex-col items-end gap-1 2xl:flex">
|
||||
<a
|
||||
href="https://github.com/TGlide/thom-chat"
|
||||
class="text-muted-foreground flex place-items-center gap-1 text-xs"
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
import Message from './message.svelte';
|
||||
import { last } from '$lib/utils/array';
|
||||
import { settings } from '$lib/state/settings.svelte';
|
||||
import Button from '$lib/components/ui/button/button.svelte';
|
||||
|
||||
const messages = useCachedQuery(api.messages.getAllFromConversation, () => ({
|
||||
conversation_id: page.params.id ?? '',
|
||||
|
|
@ -61,10 +62,20 @@
|
|||
</svelte:head>
|
||||
|
||||
<div class="flex h-full flex-1 flex-col py-4">
|
||||
{#each messages.data ?? [] as message (message._id)}
|
||||
<Message {message} />
|
||||
{/each}
|
||||
{#if conversation.data?.generating && !lastMessageHasContent}
|
||||
<LoadingDots />
|
||||
{#if !conversation.data && !conversation.isLoading}
|
||||
<div class="flex flex-1 flex-col items-center justify-center gap-4 pt-[25svh]">
|
||||
<div>
|
||||
<h1 class="text-center font-mono text-8xl font-semibold">404</h1>
|
||||
<p class="text-muted-foreground text-center text-2xl">Conversation not found</p>
|
||||
</div>
|
||||
<Button size="sm" variant="outline" href="/chat">Create a new conversation</Button>
|
||||
</div>
|
||||
{:else}
|
||||
{#each messages.data ?? [] as message (message._id)}
|
||||
<Message {message} />
|
||||
{/each}
|
||||
{#if conversation.data?.generating && !lastMessageHasContent}
|
||||
<LoadingDots />
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue