first commit

This commit is contained in:
2026-07-17 21:48:37 +05:30
commit f85599dac5
124 changed files with 10775 additions and 0 deletions
@@ -0,0 +1,85 @@
"use client";
import { useThread, useChannel, useSdk, notifyChannelChanged } from "@lynkd/messaging-inbox-sdk";
import { useUi } from "@/lib/ui-state";
import { MessageItem } from "./MessageItem";
import { Composer } from "./Composer";
import { X } from "lucide-react";
export function ThreadPanel() {
const { thread, closeThread, toast } = useUi();
const { client } = useSdk();
const channel = useChannel(thread?.channelId ?? null);
const { parent, replies, reply, react, pin, save, edit, remove } = useThread(
thread?.channelId ?? null,
thread?.parentId ?? null,
);
if (!thread) return null;
const channelLabel = channel ? (channel.kind === "channel" ? `#${channel.name}` : channel.name) : "channel";
return (
<aside
role="dialog"
aria-label="Thread"
className="fixed inset-0 z-40 flex w-full flex-col border-l border-border bg-surface md:static md:z-auto md:w-[400px] md:max-w-[400px] md:shrink-0 animate-fade-in"
>
<div className="flex h-[60px] items-center justify-between border-b border-border px-4">
<div>
<div className="text-[15px] font-bold">Thread</div>
<div className="text-[12px] text-muted">
{channel ? (channel.kind === "channel" ? `#${channel.name}` : channel.name) : ""}
</div>
</div>
<button onClick={closeThread} className="focus-ring grid h-8 w-8 place-items-center rounded-control text-muted hover:bg-hover hover:text-ink" aria-label="Close thread">
<X size={18} />
</button>
</div>
<div className="min-h-0 flex-1 overflow-y-auto pb-2">
{parent && (
<MessageItem
message={parent}
onReact={(e) => react(parent.id, e)}
onPin={() => pin(parent.id)}
onSave={() => save(parent.id)}
onEdit={(b) => edit(parent.id, b)}
onDelete={() => { remove(parent.id); closeThread(); }}
/>
)}
<div className="my-1 flex items-center gap-3 px-4">
<div className="h-px flex-1 bg-border" />
<span className="text-[11px] font-semibold text-muted">
{replies.length} {replies.length === 1 ? "reply" : "replies"}
</span>
<div className="h-px flex-1 bg-border" />
</div>
{replies.map((m) => (
<MessageItem
key={m.id}
message={m}
onReact={(e) => react(m.id, e)}
onPin={() => pin(m.id)}
onSave={() => save(m.id)}
onEdit={(b) => edit(m.id, b)}
onDelete={() => remove(m.id)}
/>
))}
</div>
<Composer
showAlsoSend
channelName={channelLabel}
placeholder="Reply…"
onSend={async (body, opts) => {
await reply(body, { attachments: opts?.attachments });
if (opts?.alsoSendToChannel && thread) {
await client.sendMessage(thread.channelId, body, { attachments: opts?.attachments, threadRootId: thread.parentId });
notifyChannelChanged(thread.channelId);
toast(`Also sent to ${channelLabel}`, "success");
}
}}
/>
</aside>
);
}