feat: update Makelore modules and conversations
Some checks failed
Electron E2E / Electron E2E (macos-latest) (push) Has been cancelled
Electron E2E / Electron E2E (ubuntu-latest) (push) Has been cancelled
Electron E2E / Electron E2E (windows-latest) (push) Has been cancelled

This commit is contained in:
inman
2026-07-31 10:08:41 +08:00
parent b8ca3f8eea
commit 80e8386fa6
175 changed files with 8036 additions and 10581 deletions

View File

@@ -1,20 +1,30 @@
/**
* TitleBar Component
* macOS: empty drag region (native traffic lights handled by hiddenInset).
* macOS: light application toolbar with native traffic lights handled by hiddenInset.
* Windows: drag region with custom minimize/maximize/close controls.
* Linux: use native window chrome (no custom title bar).
*/
import { useState, useEffect } from 'react';
import { Minus, Square, X, Copy } from 'lucide-react';
import { Copy, FolderOpen, Minus, PanelLeft, PanelLeftClose, Square, X } from 'lucide-react';
import { invokeIpc } from '@/lib/api-client';
import { cn } from '@/lib/utils';
import { useSettingsStore } from '@/stores/settings';
import { useOpencodeStore } from '@/stores/opencode';
import logoWordmarkSource from '@/assets/makelore-wordmark-source.png';
export function TitleBar({ integrated = false }: { integrated?: boolean }) {
type SidebarPeekChange = (open: boolean) => void;
type TitleBarProps = {
integrated?: boolean;
sidebarPeekOpen?: boolean;
onSidebarPeekChange?: SidebarPeekChange;
};
export function TitleBar({ integrated = false, sidebarPeekOpen = false, onSidebarPeekChange }: TitleBarProps) {
const platform = window.electron?.platform;
if (platform === 'darwin') {
return <ProductTitleBar integrated={integrated} />;
return <ProductTitleBar integrated={integrated} nativeTrafficLights sidebarPeekOpen={sidebarPeekOpen} onSidebarPeekChange={onSidebarPeekChange} />;
}
// Linux keeps the native frame/title bar for better IME compatibility.
@@ -22,37 +32,122 @@ export function TitleBar({ integrated = false }: { integrated?: boolean }) {
return null;
}
return <WindowsTitleBar integrated={integrated} />;
return <WindowsTitleBar integrated={integrated} sidebarPeekOpen={sidebarPeekOpen} onSidebarPeekChange={onSidebarPeekChange} />;
}
function ProductTitleBar({ integrated, children }: { integrated: boolean; children?: React.ReactNode }) {
function ProductTitleBar({
integrated,
children,
nativeTrafficLights = false,
sidebarPeekOpen = false,
onSidebarPeekChange,
}: {
integrated: boolean;
children?: React.ReactNode;
nativeTrafficLights?: boolean;
sidebarPeekOpen?: boolean;
onSidebarPeekChange?: SidebarPeekChange;
}) {
const sidebarCollapsed = useSettingsStore((state) => state.sidebarCollapsed);
const setSidebarCollapsed = useSettingsStore((state) => state.setSidebarCollapsed);
const activeProject = useOpencodeStore((state) => state.activeProject);
const toolbarButtonClass = 'no-drag motion-press flex h-8 w-8 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-surface-subtle hover:text-foreground';
const toggleSidebar = () => setSidebarCollapsed(!sidebarCollapsed);
const handleSidebarPeekEnter = () => {
if (sidebarCollapsed) onSidebarPeekChange?.(true);
};
const handleSidebarPeekLeave = () => {
if (sidebarCollapsed) onSidebarPeekChange?.(false);
};
const sidebarHidden = sidebarCollapsed && !sidebarPeekOpen;
return (
<div
data-testid="product-titlebar"
className={cn(
'drag-region flex h-10 shrink-0 bg-[#FFFFFF] text-[#26384D]',
integrated && 'bg-[#FFFFFF]',
'glass-surface drag-region relative z-30 flex h-10 shrink-0 text-foreground',
integrated && (sidebarHidden ? 'bg-background' : 'bg-background/70'),
integrated && sidebarHidden && 'border-b border-border/80',
)}
>
{integrated ? (
<div
data-testid="titlebar-sidebar-surface"
className={cn(
'h-full shrink-0 border-r-4 border-[#26384D] bg-[#F6F8FA] transition-[width] duration-300',
sidebarCollapsed ? 'w-16' : 'w-72',
'flex h-full shrink-0 items-center gap-1 px-2 transition-[width] duration-300 ease-spring',
sidebarHidden
? nativeTrafficLights
? 'w-[132px]'
: 'w-[52px]'
: 'w-64',
sidebarHidden
? 'border-r-0 bg-background'
: 'border-r border-border/80 bg-surface-sidebar',
nativeTrafficLights && 'pl-[88px]',
)}
/>
>
<button
type="button"
data-testid="titlebar-sidebar-toggle"
aria-label={sidebarCollapsed ? (sidebarPeekOpen ? '固定侧栏' : '展开侧栏') : '折叠侧栏'}
aria-expanded={!sidebarCollapsed || sidebarPeekOpen}
title={sidebarCollapsed ? (sidebarPeekOpen ? '固定侧栏' : '展开侧栏') : '折叠侧栏'}
className={cn(toolbarButtonClass, nativeTrafficLights && 'translate-y-[3px]')}
onClick={toggleSidebar}
onPointerEnter={handleSidebarPeekEnter}
onPointerLeave={handleSidebarPeekLeave}
onFocus={handleSidebarPeekEnter}
onBlur={handleSidebarPeekLeave}
>
{sidebarCollapsed ? <PanelLeft className="h-4 w-4" /> : <PanelLeftClose className="h-4 w-4" />}
</button>
</div>
) : null}
<div className="flex min-w-0 flex-1 items-center justify-end bg-[#FFFFFF]">
{children}
</div>
{integrated ? (
<div
data-testid="titlebar-main-surface"
className={cn(
'flex min-w-0 flex-1',
sidebarHidden ? 'border-b-0' : 'border-b border-border/80',
)}
>
<div
data-testid="titlebar-project-context"
className={cn(
'flex min-w-0 flex-1 items-center gap-2 px-3',
nativeTrafficLights && 'translate-y-[3px]',
)}
>
<FolderOpen className="h-4 w-4 shrink-0 text-muted-foreground" aria-hidden="true" />
<span className="truncate text-sm font-semibold">{activeProject?.name ?? 'Makelore 工作台'}</span>
</div>
<div className={cn(
'flex min-w-0 items-center justify-end gap-1 px-2',
nativeTrafficLights && 'translate-y-[3px]',
)}>
<div
data-testid="titlebar-logo"
className="relative mr-1 h-6 w-24 shrink-0 overflow-hidden"
>
<img
src={logoWordmarkSource}
alt="Makelore logo"
data-logo-variant="wordmark"
data-logo-source="original-wordmark"
className="h-full w-full object-cover object-center"
/>
</div>
{children}
</div>
</div>
) : (
<div className="flex min-w-0 flex-1 items-center justify-end gap-1 px-2">{children}</div>
)}
</div>
);
}
function WindowsTitleBar({ integrated }: { integrated: boolean }) {
function WindowsTitleBar({ integrated, sidebarPeekOpen, onSidebarPeekChange }: Omit<TitleBarProps, 'integrated'> & { integrated: boolean }) {
const [maximized, setMaximized] = useState(false);
useEffect(() => {
@@ -79,25 +174,25 @@ function WindowsTitleBar({ integrated }: { integrated: boolean }) {
};
return (
<ProductTitleBar integrated={integrated}>
<ProductTitleBar integrated={integrated} sidebarPeekOpen={sidebarPeekOpen} onSidebarPeekChange={onSidebarPeekChange}>
<div className="no-drag flex h-full">
<button
onClick={handleMinimize}
className="flex h-full w-11 items-center justify-center text-muted-foreground hover:bg-accent transition-colors"
className="motion-press flex h-full w-11 items-center justify-center text-muted-foreground hover:bg-surface-subtle"
title="Minimize"
>
<Minus className="h-4 w-4" />
</button>
<button
onClick={handleMaximize}
className="flex h-full w-11 items-center justify-center text-muted-foreground hover:bg-accent transition-colors"
className="motion-press flex h-full w-11 items-center justify-center text-muted-foreground hover:bg-surface-subtle"
title={maximized ? 'Restore' : 'Maximize'}
>
{maximized ? <Copy className="h-3.5 w-3.5" /> : <Square className="h-3.5 w-3.5" />}
</button>
<button
onClick={handleClose}
className="flex h-full w-11 items-center justify-center text-muted-foreground hover:bg-red-500 hover:text-white transition-colors"
className="motion-press flex h-full w-11 items-center justify-center text-muted-foreground hover:bg-accent hover:text-primary-foreground"
title="Close"
>
<X className="h-4 w-4" />