mirror of
https://github.com/JefferyHcool/BiliNote.git
synced 2026-05-06 20:42:52 +08:00
feat(chat): 问答面板支持半屏和全屏两种模式
- 半屏模式:ChatPanel 与 markdown 各占一半并排显示 - 全屏模式:ChatPanel 占满整个内容区域,隐藏 markdown - Header 新增两个按钮(问答 / 全屏问答),点击切换,再次点击关闭 - 当前激活的模式按钮高亮显示 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Copy, Download, BrainCircuit, MessageSquare } from 'lucide-react'
|
import { Copy, Download, BrainCircuit, MessageSquare, PanelRight, Maximize2 } from 'lucide-react'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'
|
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'
|
||||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||||
@@ -28,8 +28,8 @@ interface NoteHeaderProps {
|
|||||||
onDownload: () => void
|
onDownload: () => void
|
||||||
createAt?: string | Date
|
createAt?: string | Date
|
||||||
setShowTranscribe: (show: boolean) => void
|
setShowTranscribe: (show: boolean) => void
|
||||||
showChat?: boolean
|
showChat?: false | 'half' | 'full'
|
||||||
setShowChat?: (show: boolean) => void
|
setShowChat?: (mode: false | 'half' | 'full') => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export function MarkdownHeader({
|
export function MarkdownHeader({
|
||||||
@@ -188,22 +188,40 @@ export function MarkdownHeader({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
{setShowChat && (
|
{setShowChat && (
|
||||||
|
<div className="flex items-center gap-0.5 ml-1">
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => setShowChat(!showChat)}
|
onClick={() => setShowChat(showChat === 'half' ? false : 'half')}
|
||||||
variant="ghost"
|
variant={showChat === 'half' ? 'default' : 'ghost'}
|
||||||
size="sm"
|
size="sm"
|
||||||
className="h-8 px-2"
|
className="h-8 px-2"
|
||||||
>
|
>
|
||||||
<MessageSquare className="mr-1.5 h-4 w-4" />
|
<PanelRight className="mr-1.5 h-4 w-4" />
|
||||||
<span className="text-sm">AI 问答</span>
|
<span className="text-sm">问答</span>
|
||||||
</Button>
|
</Button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>基于笔记内容的 AI 问答</TooltipContent>
|
<TooltipContent>侧边问答(半屏)</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<Button
|
||||||
|
onClick={() => setShowChat(showChat === 'full' ? false : 'full')}
|
||||||
|
variant={showChat === 'full' ? 'default' : 'ghost'}
|
||||||
|
size="sm"
|
||||||
|
className="h-8 px-2"
|
||||||
|
>
|
||||||
|
<Maximize2 className="mr-1.5 h-4 w-4" />
|
||||||
|
<span className="text-sm">全屏问答</span>
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>全屏问答</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ const MarkdownViewer: FC<MarkdownViewerProps> = ({ status }) => {
|
|||||||
const retryTask = useTaskStore.getState().retryTask
|
const retryTask = useTaskStore.getState().retryTask
|
||||||
const isMultiVersion = Array.isArray(currentTask?.markdown)
|
const isMultiVersion = Array.isArray(currentTask?.markdown)
|
||||||
const [showTranscribe, setShowTranscribe] = useState(false)
|
const [showTranscribe, setShowTranscribe] = useState(false)
|
||||||
const [showChat, setShowChat] = useState(false)
|
const [showChat, setShowChat] = useState<false | 'half' | 'full'>(false)
|
||||||
const [viewMode, setViewMode] = useState<'map' | 'preview'>('preview')
|
const [viewMode, setViewMode] = useState<'map' | 'preview'>('preview')
|
||||||
const svgRef = useRef<SVGSVGElement>(null)
|
const svgRef = useRef<SVGSVGElement>(null)
|
||||||
// 多版本内容处理
|
// 多版本内容处理
|
||||||
@@ -220,6 +220,13 @@ const MarkdownViewer: FC<MarkdownViewerProps> = ({ status }) => {
|
|||||||
) : (
|
) : (
|
||||||
<div className="flex flex-1 overflow-hidden bg-white py-2">
|
<div className="flex flex-1 overflow-hidden bg-white py-2">
|
||||||
{selectedContent && selectedContent !== 'loading' && selectedContent !== 'empty' ? (
|
{selectedContent && selectedContent !== 'loading' && selectedContent !== 'empty' ? (
|
||||||
|
<>
|
||||||
|
{/* 全屏问答模式:隐藏 markdown,ChatPanel 占满 */}
|
||||||
|
{showChat === 'full' && currentTask ? (
|
||||||
|
<div className="h-full w-full">
|
||||||
|
<ChatPanel taskId={currentTask.id} />
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
<>
|
<>
|
||||||
<ScrollArea className="min-w-0 flex-1">
|
<ScrollArea className="min-w-0 flex-1">
|
||||||
<div className={'markdown-body w-full px-2'}>
|
<div className={'markdown-body w-full px-2'}>
|
||||||
@@ -476,12 +483,15 @@ const MarkdownViewer: FC<MarkdownViewerProps> = ({ status }) => {
|
|||||||
<TranscriptViewer />
|
<TranscriptViewer />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{showChat && currentTask && (
|
{/* 侧边问答模式:markdown + ChatPanel 各占一半 */}
|
||||||
<div className="ml-2 h-full w-2/5 shrink-0">
|
{showChat === 'half' && currentTask && (
|
||||||
|
<div className="ml-2 h-full w-1/2 shrink-0">
|
||||||
<ChatPanel taskId={currentTask.id} />
|
<ChatPanel taskId={currentTask.id} />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
<div className="w-[300px] flex-col justify-items-center">
|
<div className="w-[300px] flex-col justify-items-center">
|
||||||
|
|||||||
Reference in New Issue
Block a user