feat: notes to self via self-DM
Backend: - Removed self-DM restriction in conversation Create - Added duplicate check for self-DMs (returns existing one) Frontend: - ConversationList: [📝] button creates/opens notes to self - Self-DMs show as 'Notes' with 📝 icon in sidebar - DMChat header shows 'Notes' for self-DMs
This commit is contained in:
@@ -8,11 +8,16 @@ function otherMemberName(conv: { members: { id: string; username: string }[] },
|
||||
return other?.username || "unknown";
|
||||
}
|
||||
|
||||
function isSelfDM(conv: { members: { id: string }[] }, currentUserId: string) {
|
||||
return conv.members.length === 1 && conv.members[0].id === currentUserId;
|
||||
}
|
||||
|
||||
export function ConversationList() {
|
||||
const conversations = useConversationStore((s) => s.conversations);
|
||||
const activeId = useConversationStore((s) => s.activeConversationId);
|
||||
const fetchConversations = useConversationStore((s) => s.fetchConversations);
|
||||
const setActive = useConversationStore((s) => s.setActiveConversation);
|
||||
const createConversation = useConversationStore((s) => s.createConversation);
|
||||
const currentUser = useAuthStore((s) => s.user);
|
||||
const [showNew, setShowNew] = useState(false);
|
||||
|
||||
@@ -20,25 +25,48 @@ export function ConversationList() {
|
||||
fetchConversations();
|
||||
}, [fetchConversations]);
|
||||
|
||||
const openNotes = async () => {
|
||||
// Find existing self-DM or create one
|
||||
const existing = conversations.find((c) => isSelfDM(c, currentUser?.id || ""));
|
||||
if (existing) {
|
||||
setActive(existing.id);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await createConversation([]);
|
||||
} catch { /* ignore */ }
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-full w-56 bg-gb-bg-s border-r border-gb-bg-t flex flex-col">
|
||||
<div className="terminal-border border-t-0 border-x-0 px-3 py-2 text-gb-fg truncate flex items-center justify-between">
|
||||
<span>[DIRECT MESSAGES]</span>
|
||||
<button
|
||||
onClick={() => setShowNew(true)}
|
||||
className="terminal-button text-xs"
|
||||
title="New conversation"
|
||||
>
|
||||
[+]
|
||||
</button>
|
||||
<div className="flex gap-1">
|
||||
<button
|
||||
onClick={openNotes}
|
||||
className="terminal-button text-xs"
|
||||
title="Notes to self"
|
||||
>
|
||||
[📝]
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setShowNew(true)}
|
||||
className="terminal-button text-xs"
|
||||
title="New conversation"
|
||||
>
|
||||
[+]
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto p-2 font-mono text-sm">
|
||||
{conversations.length === 0 && (
|
||||
<p className="text-gb-fg-f">[no conversations]</p>
|
||||
)}
|
||||
{conversations.map((conv) => {
|
||||
const name =
|
||||
conv.type === "group_dm"
|
||||
const self = isSelfDM(conv, currentUser?.id || "");
|
||||
const name = self
|
||||
? "Notes"
|
||||
: conv.type === "group_dm"
|
||||
? conv.name || conv.members.map((m) => m.username).join(", ")
|
||||
: otherMemberName(conv, currentUser?.id || "");
|
||||
return (
|
||||
@@ -51,7 +79,7 @@ export function ConversationList() {
|
||||
: "hover:bg-gb-bg-t text-gb-fg-s"
|
||||
}`}
|
||||
>
|
||||
<span className="text-gb-fg-f">@</span>
|
||||
<span className="text-gb-fg-f">{self ? "📝" : "@"}</span>
|
||||
<span className="truncate">{name}</span>
|
||||
</button>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user