Changeset 0.37.10 (#222)
Co-authored-by: gobha <jasafpro@gmail.com> Co-committed-by: gobha <jasafpro@gmail.com>
This commit is contained in:
109
src/js/sw/surfaces/chat/sidebar.js
Normal file
109
src/js/sw/surfaces/chat/sidebar.js
Normal file
@@ -0,0 +1,109 @@
|
||||
// ==========================================
|
||||
// Chat Surface — Sidebar Component
|
||||
// ==========================================
|
||||
// Search bar, new chat, channels section, chats section with folders.
|
||||
// Footer has UserMenu (avatar) — all navigation lives in the menu flyout.
|
||||
|
||||
import { SidebarChannels } from './sidebar-channels.js';
|
||||
import { SidebarChats } from './sidebar-chats.js';
|
||||
import { UserMenu } from '../../shell/user-menu.js';
|
||||
|
||||
const html = window.html;
|
||||
const { useCallback } = window.hooks;
|
||||
|
||||
const PLUS_SVG = html`
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="12" y1="5" x2="12" y2="19"/>
|
||||
<line x1="5" y1="12" x2="19" y2="12"/>
|
||||
</svg>`;
|
||||
|
||||
const SEARCH_SVG = html`
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="11" cy="11" r="8"/>
|
||||
<line x1="21" y1="21" x2="16.65" y2="16.65"/>
|
||||
</svg>`;
|
||||
|
||||
const COLLAPSE_SVG = html`
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<rect x="3" y="3" width="18" height="18" rx="2"/>
|
||||
<line x1="9" y1="3" x2="9" y2="21"/>
|
||||
</svg>`;
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* sidebar: ReturnType<import('./use-sidebar.js').useSidebar>,
|
||||
* activeId: string|null,
|
||||
* onSelectChat: (id: string) => void,
|
||||
* onSelectChannel: (id: string) => void,
|
||||
* onNewChat: () => void,
|
||||
* onCollapse: () => void,
|
||||
* }} props
|
||||
*/
|
||||
export function Sidebar({ sidebar, activeId, onSelectChat, onSelectChannel, onNewChat, onCollapse }) {
|
||||
const _onSearch = useCallback((e) => {
|
||||
sidebar.setSearch(e.target.value);
|
||||
}, [sidebar.setSearch]);
|
||||
|
||||
return html`
|
||||
<div class="sw-chat-surface__sidebar" role="navigation" aria-label="Chat sidebar">
|
||||
${/* Header: new chat + collapse */''}
|
||||
<div class="sw-chat-surface__sidebar-header">
|
||||
<button class="sw-chat-surface__new-chat-btn"
|
||||
onClick=${onNewChat}
|
||||
title="New chat"
|
||||
aria-label="Start new chat">
|
||||
${PLUS_SVG}
|
||||
<span>New Chat</span>
|
||||
</button>
|
||||
<button class="sw-chat-surface__collapse-btn"
|
||||
onClick=${onCollapse}
|
||||
title="Collapse sidebar"
|
||||
aria-label="Collapse sidebar">
|
||||
${COLLAPSE_SVG}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
${/* Search */''}
|
||||
<div class="sw-chat-surface__search-wrap">
|
||||
<span class="sw-chat-surface__search-icon">${SEARCH_SVG}</span>
|
||||
<input class="sw-chat-surface__search"
|
||||
type="text"
|
||||
placeholder="Search\u2026"
|
||||
value=${sidebar.search}
|
||||
onInput=${_onSearch}
|
||||
aria-label="Search chats and channels" />
|
||||
</div>
|
||||
|
||||
${/* Scrollable content */''}
|
||||
<div class="sw-chat-surface__sidebar-body">
|
||||
<${SidebarChannels}
|
||||
channels=${sidebar.channels}
|
||||
activeId=${activeId}
|
||||
collapsed=${sidebar.collapsed.channels}
|
||||
onToggle=${() => sidebar.toggleCollapsed('channels')}
|
||||
onSelect=${onSelectChannel} />
|
||||
|
||||
<${SidebarChats}
|
||||
chatsByFolder=${sidebar.chatsByFolder}
|
||||
folders=${sidebar.folders}
|
||||
activeId=${activeId}
|
||||
collapsed=${sidebar.collapsed.chats}
|
||||
onToggle=${() => sidebar.toggleCollapsed('chats')}
|
||||
onSelect=${onSelectChat}
|
||||
onRename=${sidebar.renameChat}
|
||||
onDelete=${sidebar.deleteChat}
|
||||
onMoveToFolder=${sidebar.moveToFolder}
|
||||
onCreateFolder=${sidebar.createFolder}
|
||||
onRenameFolder=${sidebar.renameFolder}
|
||||
onDeleteFolder=${sidebar.deleteFolder} />
|
||||
</div>
|
||||
|
||||
${/* Footer: UserMenu only */''}
|
||||
<div class="sw-chat-surface__sidebar-footer">
|
||||
<${UserMenu} placement="up-right" />
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
Reference in New Issue
Block a user