added features and fixes
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import { useEffect } from "react";
|
||||
import { useMessageStore } from "../stores/message.ts";
|
||||
|
||||
interface PinnedMessagesProps {
|
||||
channelId: string;
|
||||
channelName: string;
|
||||
onClose: () => void;
|
||||
onJump?: (messageId: string) => void;
|
||||
}
|
||||
|
||||
export function PinnedMessages({ channelId, channelName, onClose, onJump }: PinnedMessagesProps) {
|
||||
const pinnedMessages = useMessageStore((s) => s.pinnedMessagesByChannel[channelId] || []);
|
||||
const fetchPinnedMessages = useMessageStore((s) => s.fetchPinnedMessages);
|
||||
const unpinMessage = useMessageStore((s) => s.unpinMessage);
|
||||
|
||||
useEffect(() => {
|
||||
fetchPinnedMessages(channelId);
|
||||
}, [channelId, fetchPinnedMessages]);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") {
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
window.addEventListener("keydown", handler);
|
||||
return () => window.removeEventListener("keydown", handler);
|
||||
}, [onClose]);
|
||||
|
||||
return (
|
||||
<div className="absolute inset-x-0 top-0 z-20 bg-gb-bg border-b border-gb-bg-t shadow-lg">
|
||||
<div className="px-3 py-2 border-b border-gb-bg-t flex items-center justify-between">
|
||||
<span className="text-xs text-gb-orange font-mono">PINNED IN #{channelName.toUpperCase()} ({pinnedMessages.length}/5)</span>
|
||||
<button onClick={onClose} className="text-xs text-gb-red hover:text-gb-orange">[x]</button>
|
||||
</div>
|
||||
<div className="max-h-64 overflow-y-auto font-mono text-xs">
|
||||
{pinnedMessages.length === 0 ? (
|
||||
<div className="px-3 py-4 text-center text-gb-fg-f">[no pinned messages in this channel]</div>
|
||||
) : (
|
||||
pinnedMessages.map((msg) => (
|
||||
<div
|
||||
key={msg.id}
|
||||
className="w-full text-left px-3 py-2 border-b border-gb-bg-t last:border-b-0 hover:bg-gb-bg-s/20 flex flex-col gap-1"
|
||||
>
|
||||
<div className="flex items-center justify-between text-gb-fg-f">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-gb-aqua font-bold"><{msg.author_username}></span>
|
||||
<span className="text-[10px] text-gb-fg-f">
|
||||
{new Date(msg.created_at).toLocaleString()}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
{onJump && (
|
||||
<button
|
||||
onClick={() => {
|
||||
onJump(msg.id);
|
||||
onClose();
|
||||
}}
|
||||
className="text-gb-aqua hover:text-gb-orange"
|
||||
title="Jump to message"
|
||||
>
|
||||
[JUMP]
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={async () => {
|
||||
if (confirm("Unpin this message?")) {
|
||||
try {
|
||||
await unpinMessage(channelId, msg.id);
|
||||
} catch (err) {
|
||||
alert(err instanceof Error ? err.message : "Failed to unpin");
|
||||
}
|
||||
}
|
||||
}}
|
||||
className="text-gb-red hover:text-gb-orange"
|
||||
title="Unpin message"
|
||||
>
|
||||
[UNPIN]
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-gb-fg break-words whitespace-pre-wrap">{msg.content}</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user