-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathChannel.svelte
More file actions
104 lines (94 loc) · 3.04 KB
/
Channel.svelte
File metadata and controls
104 lines (94 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<script lang="ts">
import Hash from "@lucide/svelte/icons/hash";
import Search from "@lucide/svelte/icons/search";
import MessageInput from "../chat/MessageInput.svelte";
import MessageList from "../chat/MessageList.svelte";
import PinnedMessages from "../chat/PinnedMessages.svelte";
import SearchResults from "../chat/SearchResults.svelte";
import { createChannelController } from "./channel.svelte.ts";
interface Props {
selectedChannelId: string;
organizationId: string;
}
let { selectedChannelId, organizationId }: Props = $props();
const controller = createChannelController(
() => selectedChannelId,
() => organizationId,
);
function autofocus(node: HTMLElement) {
node.focus();
}
</script>
<div class="flex h-full flex-col">
<!-- Channel header -->
<header
class="border-subtle flex items-center justify-between border-b px-6 py-4"
>
<div class="flex items-center gap-4">
<Hash class="size-5 opacity-60" />
<h1 class="text-base font-semibold">
{controller.selectedChannel.data?.name ?? "..."}
</h1>
{#if controller.selectedChannel.data?.description}
<span class="hidden text-sm opacity-60 sm:inline">
— {controller.selectedChannel.data.description}
</span>
{/if}
</div>
<div class="flex items-center gap-2">
{#if controller.showSearch}
<div
class="animate-in fade-in slide-in-from-right-2 relative duration-200"
>
<input
type="text"
placeholder="Search messages..."
class="input input-sm input-bordered bg-base-200 w-56 pr-8 text-sm transition-all duration-200 focus:w-64"
bind:value={controller.searchQuery}
onkeydown={(e) => e.key === "Enter" && controller.handleSearch()}
use:autofocus
/>
{#if controller.isSearching}
<span
class="loading loading-spinner loading-xs absolute top-2 right-2"
></span>
{/if}
</div>
{/if}
<button
class="btn btn-ghost btn-sm btn-square transition-all duration-200"
title="Search"
onclick={() => (controller.showSearch = !controller.showSearch)}
>
<Search
class="size-5 opacity-60 transition-opacity duration-200 hover:opacity-80"
/>
</button>
</div>
</header>
<!-- Search results -->
{#if controller.searchResults.length > 0}
<div class="border-subtle bg-base-200/50 border-b p-4">
<SearchResults
results={controller.searchResults}
onResultClick={controller.handleResultClick}
/>
</div>
{/if}
<!-- Pinned messages -->
<PinnedMessages channelId={selectedChannelId} />
<!-- Messages -->
<div class="flex-1 overflow-y-auto">
<MessageList
{organizationId}
channelId={selectedChannelId}
bind:replyingTo={controller.replyingTo}
/>
</div>
<!-- Input -->
<MessageInput
channelId={selectedChannelId}
{organizationId}
bind:replyingTo={controller.replyingTo}
/>
</div>