diff --git a/src/app.html b/src/app.html index d24ee7b..b405514 100644 --- a/src/app.html +++ b/src/app.html @@ -44,7 +44,7 @@ data-domains="flo-bit.dev" > - +
%sveltekit.body%
diff --git a/src/lib/components/ChannelButton.svelte b/src/lib/components/ChannelButton.svelte index 48b899c..9bc9d77 100644 --- a/src/lib/components/ChannelButton.svelte +++ b/src/lib/components/ChannelButton.svelte @@ -2,23 +2,24 @@ import { base } from '$app/paths'; import { page } from '$app/state'; import { Channel } from '$lib/schema'; - import { Badge, Button } from '@fuxui/base'; + import { Button } from '@fuxui/base'; import type { Loaded } from 'jazz-tools'; + import { useCurrentRoute } from '$lib/context'; + + const route = useCurrentRoute(); let { channel, - spaceId, lastReadDate, onclick }: { channel: Loaded; - spaceId: string; lastReadDate?: Date; onclick?: () => void; } = $props(); let isNew = $derived.by(() => { - if (!lastReadDate) return true; + if (!lastReadDate) return channel.mainThread?.timeline?.length !== 0; if (!channel.mainThread?.timeline) return false; let date = channel.mainThread.timeline[channel.mainThread.timeline.length - 1]?.createdAt; if (!date) return false; @@ -28,9 +29,9 @@ + + {#if allowThreadCreation} + + {/if} + { open = false; diff --git a/src/lib/components/ChatMessageThread.svelte b/src/lib/components/ChatMessageThread.svelte new file mode 100644 index 0000000..386da5e --- /dev/null +++ b/src/lib/components/ChatMessageThread.svelte @@ -0,0 +1,48 @@ + + +
+
+ + Thread + + + {thread.current?.name} + ({thread.current?.timeline?.length} messages) +
+ + + +
diff --git a/src/lib/components/ReplyMessage.svelte b/src/lib/components/ReplyMessage.svelte index 16d7007..bbb54bb 100644 --- a/src/lib/components/ReplyMessage.svelte +++ b/src/lib/components/ReplyMessage.svelte @@ -4,19 +4,19 @@ import { CoState } from 'jazz-svelte'; let { - replyTo + replyToId }: { - replyTo: string; + replyToId: string; } = $props(); - let message = $derived(new CoState(Message, replyTo)); + let message = $derived(new CoState(Message, replyToId)); let profile = $derived( new CoState(MyAppProfile, message.current?._edits.content?.by?.profile?.id) ); {#if message.current} -
+
diff --git a/src/lib/components/ThreadButton.svelte b/src/lib/components/ThreadButton.svelte new file mode 100644 index 0000000..7f4cc5e --- /dev/null +++ b/src/lib/components/ThreadButton.svelte @@ -0,0 +1,75 @@ + + +{#if isNew || (!onlyShowIfRecent || isRecent)} +
+ +
+{/if} diff --git a/src/lib/context.ts b/src/lib/context.ts index eb67f88..b5d053b 100644 --- a/src/lib/context.ts +++ b/src/lib/context.ts @@ -1,18 +1,6 @@ -import type { Loaded } from 'jazz-tools'; import { getContext } from 'svelte'; -import type { MyAppAccount, Space } from './schema'; -export function useMe(): { current: Loaded } | undefined { - const me = getContext('me'); - return me as { current: Loaded }; -} - -export function useSpace(): { current: Loaded } | undefined { - const space = getContext('space'); - return space as { current: Loaded }; -} - -export function useSpaceId(): string { - const spaceId = getContext('spaceId'); - return spaceId as string; +export function useCurrentRoute(): { spaceId?: string; channelId?: string; threadId?: string } { + const route = getContext('route'); + return route as { spaceId?: string; channelId?: string; threadId?: string }; } diff --git a/src/lib/schema.ts b/src/lib/schema.ts index a62dbbe..5caefb9 100644 --- a/src/lib/schema.ts +++ b/src/lib/schema.ts @@ -14,7 +14,9 @@ export const Message = co.map({ replyTo: z.string().optional(), reactions: co.list(Reaction), - type: z.enum(['message', 'announcement']) + type: z.enum(['message', 'announcement']), + + thread: z.string().optional() }); export const Timeline = co.list(Message); diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index e6ec875..ccf8bf8 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -5,8 +5,25 @@ import { JazzProvider } from 'jazz-svelte'; import { MyAppAccount } from '$lib/schema'; import { dev } from '$app/environment'; + import { setContext } from 'svelte'; + import { page } from '$app/state'; + import { afterNavigate } from '$app/navigation'; let { children } = $props(); + + let route = $state({ + spaceId: page.params.spaceId, + channelId: page.params.channelId, + threadId: page.params.threadId + }); + + setContext('route', route); + + afterNavigate(() => { + route.spaceId = page.params.spaceId; + route.channelId = page.params.channelId; + route.threadId = page.params.threadId; + }); - import { - Avatar, - Button, - cn, - Heading, - Input, - Modal, - Subheading, - Textarea, - ThemeToggle - } from '@fuxui/base'; - + import { Avatar, Button, cn, Heading, Input, Modal, Subheading, ThemeToggle } from '@fuxui/base'; import { AccountCoState, CoState } from 'jazz-svelte'; import { LastReadList, MyAppAccount, SpaceList } from '$lib/schema'; - import { createPublicSpacesList, createSpace } from '$lib/utils'; - import { getRandomUsername } from '$lib/username'; + import { createSpace } from '$lib/utils'; import { getProfile, resolveHandle } from '$lib/bluesky'; import { ImageDefinition } from 'jazz-tools'; import { onDestroy } from 'svelte'; @@ -116,8 +104,10 @@
-
-
+
+
@@ -127,8 +117,12 @@
- -
diff --git a/src/routes/[spaceId]/channel/[channelId]/+page.svelte b/src/routes/[spaceId]/channel/[channelId]/+page.svelte index 7d05420..5ac49ac 100644 --- a/src/routes/[spaceId]/channel/[channelId]/+page.svelte +++ b/src/routes/[spaceId]/channel/[channelId]/+page.svelte @@ -1,27 +1,36 @@
{#each channel.current?.mainThread?.timeline ?? [] as message, index} {#if message} - + { + threadMessage = message; + createThreadModalOpen = true; + }} + /> {/if} {/each} {#if channel.current?.mainThread?.timeline?.length === 0} -
+
No messages yet. Be the first to send a message!
{/if}
- \ No newline at end of file +/> + + +
+ create new thread + {#if threadMessage} +
+ +
+ {/if} +
+ + +
+
+
diff --git a/src/routes/[spaceId]/channel/[channelId]/thread/[threadId]/+page.svelte b/src/routes/[spaceId]/channel/[channelId]/thread/[threadId]/+page.svelte new file mode 100644 index 0000000..e1c89aa --- /dev/null +++ b/src/routes/[spaceId]/channel/[channelId]/thread/[threadId]/+page.svelte @@ -0,0 +1,162 @@ + + +
+ {#each thread.current?.timeline ?? [] as message, index} + {#if message} + + {/if} + {/each} + {#if thread.current?.timeline?.length === 0} +
+ No messages yet. Be the first to send a message! +
+ {/if} +
+ +