feat(frontend): channel sidebar toggle, member list default closed, fix accent-fg colors
This commit is contained in:
parent
e43d9fc8bf
commit
43e2d26ea2
@ -29,6 +29,7 @@ function ProjectRoomInner() {
|
|||||||
members,
|
members,
|
||||||
} = useRoom();
|
} = useRoom();
|
||||||
|
|
||||||
|
const [showChannelSidebar, setShowChannelSidebar] = useState(true);
|
||||||
const [createDialogOpen, setCreateDialogOpen] = useState(false);
|
const [createDialogOpen, setCreateDialogOpen] = useState(false);
|
||||||
const [editDialogOpen, setEditDialogOpen] = useState(false);
|
const [editDialogOpen, setEditDialogOpen] = useState(false);
|
||||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
||||||
@ -119,16 +120,18 @@ function ProjectRoomInner() {
|
|||||||
return (
|
return (
|
||||||
<div className="discord-layout">
|
<div className="discord-layout">
|
||||||
{/* Channel sidebar */}
|
{/* Channel sidebar */}
|
||||||
<DiscordChannelSidebar
|
{showChannelSidebar && (
|
||||||
projectName={projectName}
|
<DiscordChannelSidebar
|
||||||
rooms={rooms}
|
projectName={projectName}
|
||||||
selectedRoomId={activeRoomId}
|
rooms={rooms}
|
||||||
onSelectRoom={handleSelectRoom}
|
selectedRoomId={activeRoomId}
|
||||||
onCreateRoom={handleOpenCreate}
|
onSelectRoom={handleSelectRoom}
|
||||||
categories={categories.map((c) => ({ id: c.id, name: c.name }))}
|
onCreateRoom={handleOpenCreate}
|
||||||
onCreateCategory={handleCreateCategory}
|
categories={categories.map((c) => ({ id: c.id, name: c.name }))}
|
||||||
onMoveRoomToCategory={handleMoveRoomToCategory}
|
onCreateCategory={handleCreateCategory}
|
||||||
/>
|
onMoveRoomToCategory={handleMoveRoomToCategory}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Main chat area */}
|
{/* Main chat area */}
|
||||||
{activeRoom ? (
|
{activeRoom ? (
|
||||||
@ -136,6 +139,8 @@ function ProjectRoomInner() {
|
|||||||
room={activeRoom}
|
room={activeRoom}
|
||||||
isAdmin={isAdmin}
|
isAdmin={isAdmin}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
|
onToggleChannelSidebar={() => setShowChannelSidebar((v) => !v)}
|
||||||
|
channelSidebarOpen={showChannelSidebar}
|
||||||
onDelete={() => setDeleteDialogOpen(true)}
|
onDelete={() => setDeleteDialogOpen(true)}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import type { MessageWithMeta } from '@/contexts';
|
|||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import {
|
import {
|
||||||
Hash, Lock, Users, Search, ChevronLeft,
|
Hash, Lock, Users, Search, ChevronLeft,
|
||||||
AtSign, Pin, Settings,
|
AtSign, Pin, Settings, PanelLeft,
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
useCallback,
|
useCallback,
|
||||||
@ -38,9 +38,11 @@ interface DiscordChatPanelProps {
|
|||||||
isAdmin: boolean;
|
isAdmin: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onDelete: () => void;
|
onDelete: () => void;
|
||||||
|
onToggleChannelSidebar: () => void;
|
||||||
|
channelSidebarOpen: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DiscordChatPanel({ room, isAdmin, onClose, onDelete }: DiscordChatPanelProps) {
|
export function DiscordChatPanel({ room, isAdmin, onClose, onDelete, onToggleChannelSidebar, channelSidebarOpen }: DiscordChatPanelProps) {
|
||||||
const {
|
const {
|
||||||
messages,
|
messages,
|
||||||
members,
|
members,
|
||||||
@ -67,7 +69,7 @@ export function DiscordChatPanel({ room, isAdmin, onClose, onDelete }: DiscordCh
|
|||||||
const [selectedMessageForHistory, setSelectedMessageForHistory] = useState<string>('');
|
const [selectedMessageForHistory, setSelectedMessageForHistory] = useState<string>('');
|
||||||
const [showSettings, setShowSettings] = useState(false);
|
const [showSettings, setShowSettings] = useState(false);
|
||||||
const [showMentions, setShowMentions] = useState(false);
|
const [showMentions, setShowMentions] = useState(false);
|
||||||
const [showMemberList, setShowMemberList] = useState(true);
|
const [showMemberList, setShowMemberList] = useState(false);
|
||||||
const [showSearch, setShowSearch] = useState(false);
|
const [showSearch, setShowSearch] = useState(false);
|
||||||
const [activeThread, setActiveThread] = useState<{ thread: RoomThreadResponse; parentMessage: MessageWithMeta } | null>(null);
|
const [activeThread, setActiveThread] = useState<{ thread: RoomThreadResponse; parentMessage: MessageWithMeta } | null>(null);
|
||||||
const [isUpdatingRoom, setIsUpdatingRoom] = useState(false);
|
const [isUpdatingRoom, setIsUpdatingRoom] = useState(false);
|
||||||
@ -79,7 +81,8 @@ export function DiscordChatPanel({ room, isAdmin, onClose, onDelete }: DiscordCh
|
|||||||
|
|
||||||
const handleSend = useCallback(
|
const handleSend = useCallback(
|
||||||
(content: string) => {
|
(content: string) => {
|
||||||
sendMessage(content, 'text', replyingTo?.id ?? undefined);
|
const attachmentIds = messageInputRef.current?.getAttachmentIds() ?? [];
|
||||||
|
sendMessage(content, 'text', replyingTo?.id ?? undefined, attachmentIds.length > 0 ? attachmentIds : undefined);
|
||||||
setReplyingTo(null);
|
setReplyingTo(null);
|
||||||
messageInputRef.current?.clearContent();
|
messageInputRef.current?.clearContent();
|
||||||
},
|
},
|
||||||
@ -260,6 +263,18 @@ export function DiscordChatPanel({ room, isAdmin, onClose, onDelete }: DiscordCh
|
|||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="flex h-8 w-8 items-center justify-center rounded-md transition-colors"
|
||||||
|
style={{
|
||||||
|
color: channelSidebarOpen ? 'var(--room-accent)' : 'var(--room-text-muted)',
|
||||||
|
background: channelSidebarOpen ? 'var(--room-channel-active)' : 'transparent',
|
||||||
|
}}
|
||||||
|
onClick={onToggleChannelSidebar}
|
||||||
|
title={channelSidebarOpen ? 'Hide channels' : 'Show channels'}
|
||||||
|
>
|
||||||
|
<PanelLeft className="h-4 w-4" />
|
||||||
|
</button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|||||||
@ -204,7 +204,7 @@ export const RoomSettingsPanel = memo(function RoomSettingsPanel({
|
|||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
disabled={!name.trim() || isPending}
|
disabled={!name.trim() || isPending}
|
||||||
className="w-full border-none"
|
className="w-full border-none"
|
||||||
style={{ background: 'var(--room-accent)', color: '#fff' }}
|
style={{ background: 'var(--room-accent)', color: 'var(--accent-fg)' }}
|
||||||
>
|
>
|
||||||
{isPending ? (
|
{isPending ? (
|
||||||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||||||
@ -264,7 +264,7 @@ export const RoomSettingsPanel = memo(function RoomSettingsPanel({
|
|||||||
{config.think && (
|
{config.think && (
|
||||||
<span
|
<span
|
||||||
className="rounded px-1 py-0.5 text-[10px] shrink-0"
|
className="rounded px-1 py-0.5 text-[10px] shrink-0"
|
||||||
style={{ background: 'rgba(59,130,246,0.1)', color: 'var(--room-accent)' }}
|
style={{ background: 'var(--accent-subtle)', color: 'var(--room-accent)' }}
|
||||||
>
|
>
|
||||||
think
|
think
|
||||||
</span>
|
</span>
|
||||||
@ -439,7 +439,7 @@ export const RoomSettingsPanel = memo(function RoomSettingsPanel({
|
|||||||
<Button
|
<Button
|
||||||
onClick={handleAddAi}
|
onClick={handleAddAi}
|
||||||
disabled={!selectedModelId || isAddingAi}
|
disabled={!selectedModelId || isAddingAi}
|
||||||
style={{ background: 'var(--room-accent)', color: '#fff', border: 'none' }}
|
style={{ background: 'var(--room-accent)', color: 'var(--accent-fg)', border: 'none' }}
|
||||||
>
|
>
|
||||||
{isAddingAi ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}
|
{isAddingAi ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}
|
||||||
Add Model
|
Add Model
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user