Skip to content

Commit de644b6

Browse files
committed
Add new features to chat window
1 parent af89fa6 commit de644b6

File tree

4 files changed

+160
-23
lines changed

4 files changed

+160
-23
lines changed

src/lib/docs/ComponentSubHeader.svelte

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
let { title, description }: { title: string; description?: string } = $props();
33
</script>
44

5-
<div class="flex flex-col gap-4 mt-8">
6-
<div class="text-xl font-semibold tracking-wider">{title}</div>
7-
<div>{description}</div>
5+
<div class="flex flex-col gap-4 mt-32 mb-4 p-4 rounded bg-gray-200">
6+
<div class="text-xl tracking-wider">{title}</div>
7+
{#if description}
8+
<div>{description}</div>
9+
{/if}
810
</div>

src/lib/modules/chat/ChatWindow.svelte

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,45 @@
1414
import Date from "../utils/date/Date.svelte";
1515
import type { ChatMessage, ChatUser } from "./chat-message";
1616
17-
let { messages, users, meId }: { messages: ChatMessage[]; users: ChatUser[]; meId: string } =
18-
$props();
17+
let {
18+
messages = [],
19+
users = [],
20+
meId,
21+
showAvatars = "always"
22+
}: {
23+
messages: ChatMessage[];
24+
users: ChatUser[];
25+
meId: string;
26+
showAvatars?: "never" | "always" | "change";
27+
} = $props();
28+
29+
const scrollToBottom = (node, dependency) => {
30+
const scroll = () =>
31+
node.scroll({
32+
top: node.scrollHeight,
33+
behavior: "smooth"
34+
});
35+
scroll();
36+
37+
return { update: scroll };
38+
};
1939
</script>
2040

21-
<div class="w-full h-full overflow-hidden overflow-y-auto">
41+
<div class="w-full h-full overflow-hidden overflow-y-auto" use:scrollToBottom={messages}>
2242
{#each messages as message, i (message.id)}
2343
<div class="chat {message.senderId === meId ? 'chat-start' : 'chat-end'}">
24-
<div class="chat-image avatar">
25-
<div class="w-10 rounded-box">
26-
{#if messages[i + 1]?.senderId !== message.senderId}
27-
<img
28-
alt="Tailwind CSS chat bubble component"
29-
src={users.find((user) => user.id === message.senderId)?.avatarUrl}
30-
/>
31-
{/if}
44+
{#if showAvatars !== "never"}
45+
<div class="chat-image avatar">
46+
<div class="w-10 rounded-box">
47+
{#if showAvatars === "always" || (showAvatars === "change" && messages[i + 1]?.senderId !== message.senderId)}
48+
<img
49+
alt="Tailwind CSS chat bubble component"
50+
src={users.find((user) => user.id === message.senderId)?.avatarUrl}
51+
/>
52+
{/if}
53+
</div>
3254
</div>
33-
</div>
55+
{/if}
3456
<div class="chat-bubble {message.senderId === meId ? 'chat-start' : 'chat-end'}">
3557
{message.text}
3658
</div>

src/routes/modules/chat/chat-window/+page.svelte

Lines changed: 110 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<script lang="ts">
22
import { ONE_SECOND } from "$lib/constants/date.constants";
33
import ComponentHeader from "$lib/docs/ComponentHeader.svelte";
4+
import ComponentPlayground from "$lib/docs/ComponentPlayground.svelte";
5+
import ComponentSubHeader from "$lib/docs/ComponentSubHeader.svelte";
46
import ChatWindow from "$lib/modules/chat/ChatWindow.svelte";
57
68
const users = [
@@ -47,23 +49,123 @@
4749
text: "I said a hip hop - Hippie to the hippie - The hip, hip a hop, and you don't stop, a rock it out",
4850
senderId: "1",
4951
createdAt: Date.now() - 1000 * 60 * 5 + ONE_SECOND * 10
50-
},
52+
}
53+
];
54+
55+
const longMessages = $state([
56+
...messages,
5157
{
5258
id: "6",
5359
text: "Bubba to the bang bang boogie, boobie to the boogie - To the rhythm of the boogie the beat. Now, what you hear is not a test I'm rappin' to the beat - And me, the groove, and my friends are gonna try to move your feet - See, I am Wonder Mike, and I'd like to say hello - To the black, to the white, the red and the brown- The purple and yellow, but first, I gotta - Bang bang, the boogie to the boogie -- Say up jump the boogie to the bang bang boogie -Let's rock, you don't stop - Rock the rhythm that'll make your body rock - Well so far you've heard my voice but I brought two friends along - And the next on the mic is my man Hank - C'mon, Hank, sing that song, check it out - Well, I'm Imp the Dimp, the ladies' pimp - The women fight for my delight - But I'm the grandmaster with the three MCs - That shock the house for the young ladies - And when you come inside, into the front - You do the Freak, Spank, and do the Bump",
5460
senderId: "1",
5561
createdAt: Date.now()
5662
}
57-
];
63+
]);
5864
</script>
5965

60-
<ComponentHeader title="Chat Window"></ComponentHeader>
66+
<ComponentHeader
67+
title="Chat Window"
68+
description="Shows a thread window as known from various messengers"
69+
></ComponentHeader>
70+
71+
<div class="flex flex-col justify-center items-center gap-4">
72+
<ComponentPlayground>
73+
<ChatWindow meId="1" {users} {messages}></ChatWindow>
74+
</ComponentPlayground>
75+
</div>
76+
77+
<table class="table table-zebra">
78+
<thead>
79+
<tr>
80+
<th>Option</th>
81+
<th>Type</th>
82+
<th>Default</th>
83+
<th>Description</th>
84+
</tr>
85+
</thead>
86+
<tbody>
87+
<tr>
88+
<td>messages</td>
89+
<td>Array&lt;ChatMessage&gt;</td>
90+
<td>[]</td>
91+
<td>Array of messages to display</td>
92+
</tr>
93+
<tr>
94+
<td>users</td>
95+
<td>Array&lt;ChatUser&gt;</td>
96+
<td>[]</td>
97+
<td>Array of users to display avatars</td>
98+
</tr>
99+
<tr>
100+
<td>meId</td>
101+
<td>String</td>
102+
<td></td>
103+
<td>Id of the user who is currently logged in and therefor shown on the left</td>
104+
</tr>
105+
<tr>
106+
<td>showAvatars</td>
107+
<td>"never" | "always" | "change"</td>
108+
<td>"always"</td>
109+
<td>When to show avatars</td>
110+
</tr>
111+
</tbody>
112+
</table>
61113

62-
<div class="mockup-phone">
63-
<div class="camera"></div>
64-
<div class="display">
65-
<div class="artboard phone-1 h-full pt-6">
66-
<ChatWindow meId="1" {users} {messages}></ChatWindow>
114+
<ComponentSubHeader title="Show Avatars"></ComponentSubHeader>
115+
116+
<div class="flex flex-row gap-4">
117+
<div class="flex flex-col items-center grow">
118+
<div class="text-lg font-mono">showAvatars=always</div>
119+
<ComponentPlayground>
120+
<ChatWindow meId="1" {users} {messages} showAvatars="always"></ChatWindow>
121+
</ComponentPlayground>
122+
</div>
123+
<div class="flex flex-col items-center grow">
124+
<div class="text-lg font-mono">showAvatars=change</div>
125+
<ComponentPlayground>
126+
<ChatWindow meId="1" {users} {messages} showAvatars="change"></ChatWindow>
127+
</ComponentPlayground>
128+
</div>
129+
<div class="flex flex-col items-center grow">
130+
<div class="text-lg font-mono">showAvatars=never</div>
131+
<ComponentPlayground>
132+
<ChatWindow meId="1" {users} {messages} showAvatars="never"></ChatWindow>
133+
</ComponentPlayground>
134+
</div>
135+
</div>
136+
137+
<ComponentSubHeader title="Auto Scroll"></ComponentSubHeader>
138+
139+
<div class="flex flex-row gap-4">
140+
<div class="mockup-phone">
141+
<div class="camera"></div>
142+
<div class="display">
143+
<div class="artboard artboard-demo phone-1 p-1 pt-8">
144+
<ChatWindow meId="1" {users} messages={longMessages} showAvatars="always"></ChatWindow>
145+
</div>
67146
</div>
68147
</div>
148+
<button
149+
class="btn btn-primary"
150+
onclick={() => {
151+
longMessages.push({
152+
id: longMessages.length + 100 + "",
153+
text: "New message",
154+
senderId: "2",
155+
createdAt: Date.now()
156+
});
157+
}}
158+
>
159+
Add new Message
160+
</button>
69161
</div>
162+
163+
<ComponentSubHeader title="Custom Element"></ComponentSubHeader>
164+
<ComponentPlayground>
165+
<iframe
166+
src="https://stackblitz.com/edit/sui-chat-window-wc?file=src%2Fmain.ts"
167+
width="100%"
168+
height="600px"
169+
title="Chat Window as a custom element"
170+
></iframe>
171+
</ComponentPlayground>

static/img/icon_angular.svg

Lines changed: 11 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)