Refine changes panel controls
This commit is contained in:
@@ -199,7 +199,7 @@ const getTabLabel = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tab.mode === 'diff') {
|
if (tab.mode === 'diff') {
|
||||||
return tab.stagedDiff ? t('contextPanel.mode.stagedDiff') : t('contextPanel.mode.workingDiff');
|
return t('contextPanel.mode.diff');
|
||||||
}
|
}
|
||||||
|
|
||||||
return getModeLabel(tab.mode, t);
|
return getModeLabel(tab.mode, t);
|
||||||
@@ -1997,6 +1997,7 @@ export const ContextPanel: React.FC = () => {
|
|||||||
const panelState = useUIStore((state) => (directoryKey ? state.contextPanelByDirectory[directoryKey] : undefined));
|
const panelState = useUIStore((state) => (directoryKey ? state.contextPanelByDirectory[directoryKey] : undefined));
|
||||||
const closeContextPanel = useUIStore((state) => state.closeContextPanel);
|
const closeContextPanel = useUIStore((state) => state.closeContextPanel);
|
||||||
const closeContextPanelTab = useUIStore((state) => state.closeContextPanelTab);
|
const closeContextPanelTab = useUIStore((state) => state.closeContextPanelTab);
|
||||||
|
const openContextPanelTab = useUIStore((state) => state.openContextPanelTab);
|
||||||
const toggleContextPanelExpanded = useUIStore((state) => state.toggleContextPanelExpanded);
|
const toggleContextPanelExpanded = useUIStore((state) => state.toggleContextPanelExpanded);
|
||||||
const setContextPanelWidth = useUIStore((state) => state.setContextPanelWidth);
|
const setContextPanelWidth = useUIStore((state) => state.setContextPanelWidth);
|
||||||
const setActiveContextPanelTab = useUIStore((state) => state.setActiveContextPanelTab);
|
const setActiveContextPanelTab = useUIStore((state) => state.setActiveContextPanelTab);
|
||||||
@@ -2178,6 +2179,18 @@ export const ContextPanel: React.FC = () => {
|
|||||||
|
|
||||||
const activeChatTabID = activeTab?.mode === 'chat' ? activeTab.id : null;
|
const activeChatTabID = activeTab?.mode === 'chat' ? activeTab.id : null;
|
||||||
|
|
||||||
|
const handleDiffScopeChange = React.useCallback((nextScope: 'working' | 'staged') => {
|
||||||
|
if (!directoryKey || activeTab?.mode !== 'diff') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
openContextPanelTab(directoryKey, {
|
||||||
|
mode: 'diff',
|
||||||
|
targetPath: activeTab.targetPath,
|
||||||
|
stagedDiff: nextScope === 'staged',
|
||||||
|
});
|
||||||
|
}, [activeTab, directoryKey, openContextPanelTab]);
|
||||||
|
|
||||||
const postThemeSyncToEmbeddedChat = React.useCallback(() => {
|
const postThemeSyncToEmbeddedChat = React.useCallback(() => {
|
||||||
if (typeof window === 'undefined') {
|
if (typeof window === 'undefined') {
|
||||||
return;
|
return;
|
||||||
@@ -2286,6 +2299,7 @@ export const ContextPanel: React.FC = () => {
|
|||||||
pinSelectedFileHeaderToTopOnNavigate
|
pinSelectedFileHeaderToTopOnNavigate
|
||||||
showOpenInEditorAction
|
showOpenInEditorAction
|
||||||
diffScope={activeTab.stagedDiff ? 'staged' : 'working'}
|
diffScope={activeTab.stagedDiff ? 'staged' : 'working'}
|
||||||
|
onDiffScopeChange={handleDiffScopeChange}
|
||||||
targetFilePath={activeTab.targetPath}
|
targetFilePath={activeTab.targetPath}
|
||||||
flushContent
|
flushContent
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -717,6 +717,7 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
const openContextOverview = useUIStore((state) => state.openContextOverview);
|
const openContextOverview = useUIStore((state) => state.openContextOverview);
|
||||||
const openContextPlan = useUIStore((state) => state.openContextPlan);
|
const openContextPlan = useUIStore((state) => state.openContextPlan);
|
||||||
const openContextBrowser = useUIStore((state) => state.openContextBrowser);
|
const openContextBrowser = useUIStore((state) => state.openContextBrowser);
|
||||||
|
const openContextPanelTab = useUIStore((state) => state.openContextPanelTab);
|
||||||
const closeContextPanel = useUIStore((state) => state.closeContextPanel);
|
const closeContextPanel = useUIStore((state) => state.closeContextPanel);
|
||||||
const contextPanelByDirectory = useUIStore((state) => state.contextPanelByDirectory);
|
const contextPanelByDirectory = useUIStore((state) => state.contextPanelByDirectory);
|
||||||
const activeMainTab = useUIStore((state) => state.activeMainTab);
|
const activeMainTab = useUIStore((state) => state.activeMainTab);
|
||||||
@@ -1495,6 +1496,21 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
openContextPlan(directory);
|
openContextPlan(directory);
|
||||||
}, [closeContextPanel, contextPanelByDirectory, openContextPlan, openDirectory]);
|
}, [closeContextPanel, contextPanelByDirectory, openContextPlan, openDirectory]);
|
||||||
|
|
||||||
|
const handleOpenContextChanges = React.useCallback(() => {
|
||||||
|
const directory = normalize(openDirectory || '');
|
||||||
|
if (!directory) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const panelState = contextPanelByDirectory[directory];
|
||||||
|
if (getActiveContextMode(panelState) === 'diff') {
|
||||||
|
closeContextPanel(directory);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
openContextPanelTab(directory, { mode: 'diff', stagedDiff: false });
|
||||||
|
}, [closeContextPanel, contextPanelByDirectory, openContextPanelTab, openDirectory]);
|
||||||
|
|
||||||
const handleOpenContextBrowser = React.useCallback(() => {
|
const handleOpenContextBrowser = React.useCallback(() => {
|
||||||
const directory = normalize(openDirectory || '');
|
const directory = normalize(openDirectory || '');
|
||||||
if (!directory) {
|
if (!directory) {
|
||||||
@@ -1519,6 +1535,15 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
return getActiveContextMode(panelState) === 'plan';
|
return getActiveContextMode(panelState) === 'plan';
|
||||||
}, [contextPanelByDirectory, openDirectory]);
|
}, [contextPanelByDirectory, openDirectory]);
|
||||||
|
|
||||||
|
const isContextChangesActive = React.useMemo(() => {
|
||||||
|
const directory = normalize(openDirectory || '');
|
||||||
|
if (!directory) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const panelState = contextPanelByDirectory[directory];
|
||||||
|
return getActiveContextMode(panelState) === 'diff';
|
||||||
|
}, [contextPanelByDirectory, openDirectory]);
|
||||||
|
|
||||||
const isContextBrowserActive = React.useMemo(() => {
|
const isContextBrowserActive = React.useMemo(() => {
|
||||||
const directory = normalize(openDirectory || '');
|
const directory = normalize(openDirectory || '');
|
||||||
if (!directory) {
|
if (!directory) {
|
||||||
@@ -1992,6 +2017,28 @@ export const Header: React.FC<HeaderProps> = ({
|
|||||||
|
|
||||||
const desktopSidebarActions = (
|
const desktopSidebarActions = (
|
||||||
<>
|
<>
|
||||||
|
{!isVSCode ? (
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
aria-label={t('header.actions.toggleChangesPanelAria')}
|
||||||
|
aria-pressed={isContextChangesActive}
|
||||||
|
onClick={handleOpenContextChanges}
|
||||||
|
className={desktopHeaderIconButtonClass}
|
||||||
|
>
|
||||||
|
<span className="relative h-5 w-5 overflow-hidden rounded-[2px]">
|
||||||
|
<span className="absolute left-[4px] top-[4px] h-3 w-[5px] bg-[var(--status-error)]/25" />
|
||||||
|
<span className="absolute right-[4px] top-[4px] h-3 w-[5px] bg-[var(--status-success)]/25" />
|
||||||
|
<Icon name="layout-column" className="absolute inset-0 h-5 w-5" />
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>
|
||||||
|
<p>{t('header.actions.toggleChangesPanel')}</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
) : null}
|
||||||
{showPlanTab && (
|
{showPlanTab && (
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
|
|||||||
@@ -176,12 +176,22 @@ const createTextDiffDataFromPatch = (filePath: string, patch: string): DiffData
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const formatDiffTotals = (insertions?: number, deletions?: number) => {
|
const formatDiffTotals = (
|
||||||
|
insertions?: number,
|
||||||
|
deletions?: number,
|
||||||
|
options?: { shrink?: boolean; className?: string },
|
||||||
|
) => {
|
||||||
const added = insertions ?? 0;
|
const added = insertions ?? 0;
|
||||||
const removed = deletions ?? 0;
|
const removed = deletions ?? 0;
|
||||||
if (!added && !removed) return null;
|
if (!added && !removed) return null;
|
||||||
return (
|
return (
|
||||||
<span className="typography-meta flex flex-shrink-0 items-center gap-1 text-xs whitespace-nowrap">
|
<span
|
||||||
|
className={cn(
|
||||||
|
'typography-meta flex items-center gap-1 text-xs whitespace-nowrap',
|
||||||
|
options?.shrink ? 'min-w-0 overflow-hidden' : 'flex-shrink-0',
|
||||||
|
options?.className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
{added ? <span style={{ color: 'var(--status-success)' }}>+{added}</span> : null}
|
{added ? <span style={{ color: 'var(--status-success)' }}>+{added}</span> : null}
|
||||||
{removed ? <span style={{ color: 'var(--status-error)' }}>-{removed}</span> : null}
|
{removed ? <span style={{ color: 'var(--status-error)' }}>-{removed}</span> : null}
|
||||||
</span>
|
</span>
|
||||||
@@ -232,6 +242,7 @@ interface FileSelectorProps {
|
|||||||
selectedFile: string | null;
|
selectedFile: string | null;
|
||||||
selectedFileEntry: FileEntry | null;
|
selectedFileEntry: FileEntry | null;
|
||||||
onSelectFile: (path: string) => void;
|
onSelectFile: (path: string) => void;
|
||||||
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FileSelector = React.memo<FileSelectorProps>(({
|
const FileSelector = React.memo<FileSelectorProps>(({
|
||||||
@@ -239,6 +250,7 @@ const FileSelector = React.memo<FileSelectorProps>(({
|
|||||||
selectedFile,
|
selectedFile,
|
||||||
selectedFileEntry,
|
selectedFileEntry,
|
||||||
onSelectFile,
|
onSelectFile,
|
||||||
|
className,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -247,24 +259,27 @@ const FileSelector = React.memo<FileSelectorProps>(({
|
|||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<button className="flex h-7 min-w-0 max-w-[min(52rem,60vw)] items-center gap-2 rounded-lg border border-input bg-transparent px-2 typography-ui-label text-foreground outline-none hover:bg-interactive-hover hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring">
|
<button className={cn(
|
||||||
|
'diff-toolbar__file-trigger flex h-7 min-w-[3.75rem] max-w-full items-center gap-2 rounded-lg border border-input bg-transparent px-2 typography-ui-label text-foreground outline-none hover:bg-interactive-hover hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring',
|
||||||
|
className,
|
||||||
|
)}>
|
||||||
{selectedFileEntry ? (
|
{selectedFileEntry ? (
|
||||||
<div className="flex min-w-0 flex-1 items-center gap-3">
|
<div className="diff-toolbar__file-trigger-content flex min-w-0 flex-1 items-center gap-2">
|
||||||
<FileTypeIcon filePath={selectedFileEntry.path} className="h-3.5 w-3.5 flex-shrink-0" />
|
<FileTypeIcon filePath={selectedFileEntry.path} className="h-3.5 w-3.5 flex-shrink-0" />
|
||||||
<DiffFilePathLabel path={selectedFileEntry.path} className="flex-1" />
|
<DiffFilePathLabel path={selectedFileEntry.path} className="diff-toolbar__file-label min-w-0 flex-1" />
|
||||||
{formatDiffTotals(selectedFileEntry.insertions, selectedFileEntry.deletions)}
|
{formatDiffTotals(selectedFileEntry.insertions, selectedFileEntry.deletions, { shrink: true, className: 'diff-toolbar__file-stats' })}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-muted-foreground">{t('diffView.selector.selectFile')}</span>
|
<span className="min-w-0 truncate text-muted-foreground">{t('diffView.selector.selectFile')}</span>
|
||||||
)}
|
)}
|
||||||
<Icon name="arrow-down-s" className="size-4 opacity-50" />
|
<Icon name="arrow-down-s" className="size-4 flex-shrink-0 opacity-50" />
|
||||||
</button>
|
</button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="max-h-[70vh] w-[max(var(--anchor-width),min(28rem,calc(100vw-2rem)))] max-w-[calc(100vw-2rem)] overflow-y-auto">
|
<DropdownMenuContent className="max-h-[70vh] w-[min(max(var(--anchor-width),18rem),36rem,calc(100vw-2rem))] max-w-[calc(100vw-2rem)] overflow-y-auto">
|
||||||
<DropdownMenuRadioGroup value={selectedFile ?? ''} onValueChange={onSelectFile}>
|
<DropdownMenuRadioGroup value={selectedFile ?? ''} onValueChange={onSelectFile}>
|
||||||
{changedFiles.map((file) => (
|
{changedFiles.map((file) => (
|
||||||
<DropdownMenuRadioItem key={file.path} value={file.path} className="min-w-0 items-center">
|
<DropdownMenuRadioItem key={file.path} value={file.path} className="min-w-0 items-center">
|
||||||
<div className="flex w-full min-w-0 items-center gap-3">
|
<div className="flex w-full min-w-0 items-center gap-2.5">
|
||||||
<FileTypeIcon filePath={file.path} className="h-3.5 w-3.5 flex-shrink-0" />
|
<FileTypeIcon filePath={file.path} className="h-3.5 w-3.5 flex-shrink-0" />
|
||||||
<DiffFilePathLabel path={file.path} className="flex-1" />
|
<DiffFilePathLabel path={file.path} className="flex-1" />
|
||||||
{formatDiffTotals(file.insertions, file.deletions)}
|
{formatDiffTotals(file.insertions, file.deletions)}
|
||||||
@@ -277,6 +292,64 @@ const FileSelector = React.memo<FileSelectorProps>(({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface ChangeScopeSelectorProps {
|
||||||
|
scope: Extract<DiffScope, 'working' | 'staged'>;
|
||||||
|
workingCount: number;
|
||||||
|
stagedCount: number;
|
||||||
|
onScopeChange?: (scope: Extract<DiffScope, 'working' | 'staged'>) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ChangeScopeSelector = React.memo<ChangeScopeSelectorProps>(({
|
||||||
|
scope,
|
||||||
|
workingCount,
|
||||||
|
stagedCount,
|
||||||
|
onScopeChange,
|
||||||
|
}) => {
|
||||||
|
const { t } = useI18n();
|
||||||
|
const currentCount = scope === 'staged' ? stagedCount : workingCount;
|
||||||
|
const currentLabel = scope === 'staged' ? t('diffView.scope.staged') : t('diffView.scope.changed');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger asChild>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex h-7 flex-shrink-0 items-center gap-1.5 rounded-md px-2 typography-ui-label font-semibold text-foreground outline-none hover:bg-interactive-hover focus-visible:ring-2 focus-visible:ring-ring"
|
||||||
|
aria-label={t('diffView.scope.selectorAria')}
|
||||||
|
>
|
||||||
|
<span className="whitespace-nowrap">
|
||||||
|
{currentLabel}<span className="diff-toolbar__scope-count">: {currentCount}</span>
|
||||||
|
</span>
|
||||||
|
<Icon name="arrow-down-s" className="size-4 flex-shrink-0 opacity-60" />
|
||||||
|
</button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent align="start" className="w-40">
|
||||||
|
<DropdownMenuRadioGroup
|
||||||
|
value={scope}
|
||||||
|
onValueChange={(value) => {
|
||||||
|
if (value === 'working' || value === 'staged') {
|
||||||
|
onScopeChange?.(value);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DropdownMenuRadioItem value="working">
|
||||||
|
<span className="flex min-w-0 flex-1 items-center justify-between gap-3">
|
||||||
|
<span>{t('diffView.scope.changed')}</span>
|
||||||
|
<span className="typography-meta text-muted-foreground">{workingCount}</span>
|
||||||
|
</span>
|
||||||
|
</DropdownMenuRadioItem>
|
||||||
|
<DropdownMenuRadioItem value="staged">
|
||||||
|
<span className="flex min-w-0 flex-1 items-center justify-between gap-3">
|
||||||
|
<span>{t('diffView.scope.staged')}</span>
|
||||||
|
<span className="typography-meta text-muted-foreground">{stagedCount}</span>
|
||||||
|
</span>
|
||||||
|
</DropdownMenuRadioItem>
|
||||||
|
</DropdownMenuRadioGroup>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
interface FileListProps {
|
interface FileListProps {
|
||||||
changedFiles: FileEntry[];
|
changedFiles: FileEntry[];
|
||||||
selectedFile: string | null;
|
selectedFile: string | null;
|
||||||
@@ -766,6 +839,7 @@ interface DiffViewProps {
|
|||||||
pinSelectedFileHeaderToTopOnNavigate?: boolean;
|
pinSelectedFileHeaderToTopOnNavigate?: boolean;
|
||||||
showOpenInEditorAction?: boolean;
|
showOpenInEditorAction?: boolean;
|
||||||
diffScope?: DiffScope;
|
diffScope?: DiffScope;
|
||||||
|
onDiffScopeChange?: (scope: Extract<DiffScope, 'working' | 'staged'>) => void;
|
||||||
targetFilePath?: string | null;
|
targetFilePath?: string | null;
|
||||||
/** Render diff content flush with the container edges (no outer padding). */
|
/** Render diff content flush with the container edges (no outer padding). */
|
||||||
flushContent?: boolean;
|
flushContent?: boolean;
|
||||||
@@ -778,6 +852,7 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
|||||||
pinSelectedFileHeaderToTopOnNavigate = false,
|
pinSelectedFileHeaderToTopOnNavigate = false,
|
||||||
showOpenInEditorAction = false,
|
showOpenInEditorAction = false,
|
||||||
diffScope = 'all',
|
diffScope = 'all',
|
||||||
|
onDiffScopeChange,
|
||||||
targetFilePath = null,
|
targetFilePath = null,
|
||||||
flushContent = false,
|
flushContent = false,
|
||||||
}) => {
|
}) => {
|
||||||
@@ -868,6 +943,16 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
|||||||
.sort((a, b) => a.path.localeCompare(b.path));
|
.sort((a, b) => a.path.localeCompare(b.path));
|
||||||
}, [diffScope, status]);
|
}, [diffScope, status]);
|
||||||
|
|
||||||
|
const workingFileCount = React.useMemo(() => {
|
||||||
|
if (!status?.files) return 0;
|
||||||
|
return status.files.filter(isWorkingStatusFile).length;
|
||||||
|
}, [status]);
|
||||||
|
|
||||||
|
const stagedFileCount = React.useMemo(() => {
|
||||||
|
if (!status?.files) return 0;
|
||||||
|
return status.files.filter(isStagedStatusFile).length;
|
||||||
|
}, [status]);
|
||||||
|
|
||||||
const selectedFileEntry = React.useMemo(() => {
|
const selectedFileEntry = React.useMemo(() => {
|
||||||
if (!selectedFile) return null;
|
if (!selectedFile) return null;
|
||||||
return changedFiles.find((file) => file.path === selectedFile) ?? null;
|
return changedFiles.find((file) => file.path === selectedFile) ?? null;
|
||||||
@@ -1391,18 +1476,26 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full flex-col overflow-hidden bg-background">
|
<div className="flex h-full flex-col overflow-hidden bg-background">
|
||||||
<div className="flex items-center gap-3 px-3 py-2 bg-background">
|
<div className="@container/diff-toolbar flex min-w-0 items-center gap-2 px-3 py-2 bg-background">
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<div className="flex items-center gap-1 rounded-md px-2 py-1 text-muted-foreground shrink-0">
|
diffScope === 'working' || diffScope === 'staged' ? (
|
||||||
<Icon name="git-commit" className="h-4 w-4" />
|
<ChangeScopeSelector
|
||||||
<span className="typography-ui-label font-semibold text-foreground">
|
scope={diffScope}
|
||||||
{isLoadingStatus && !status
|
workingCount={workingFileCount}
|
||||||
? t('diffView.state.loadingChanges')
|
stagedCount={stagedFileCount}
|
||||||
: (changedFiles.length === 1
|
onScopeChange={onDiffScopeChange}
|
||||||
? t('diffView.summary.changedFilesSingle', { count: changedFiles.length })
|
/>
|
||||||
: t('diffView.summary.changedFilesPlural', { count: changedFiles.length }))}
|
) : (
|
||||||
</span>
|
<div className="flex items-center gap-1 rounded-md px-2 py-1 text-muted-foreground shrink-0">
|
||||||
</div>
|
<span className="typography-ui-label font-semibold text-foreground">
|
||||||
|
{isLoadingStatus && !status
|
||||||
|
? t('diffView.state.loadingChanges')
|
||||||
|
: (changedFiles.length === 1
|
||||||
|
? t('diffView.summary.changedFilesSingle', { count: changedFiles.length })
|
||||||
|
: t('diffView.summary.changedFilesPlural', { count: changedFiles.length }))}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
)}
|
)}
|
||||||
{showFileSelector && (
|
{showFileSelector && (
|
||||||
<FileSelector
|
<FileSelector
|
||||||
@@ -1410,22 +1503,26 @@ export const DiffView: React.FC<DiffViewProps> = ({
|
|||||||
selectedFile={selectedFile}
|
selectedFile={selectedFile}
|
||||||
selectedFileEntry={selectedFileEntry}
|
selectedFileEntry={selectedFileEntry}
|
||||||
onSelectFile={handleSelectFileAndScroll}
|
onSelectFile={handleSelectFileAndScroll}
|
||||||
|
className="w-fit min-w-0"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div className="flex-1" />
|
{!showFileSelector ? <div className="min-w-0 flex-1" /> : null}
|
||||||
{changedFiles.length > 0 && (
|
{changedFiles.length > 0 && (
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={handleExpandOrCollapseAll}
|
onClick={handleExpandOrCollapseAll}
|
||||||
className="h-7 gap-1.5 px-2 text-muted-foreground hover:text-foreground"
|
className={cn(
|
||||||
|
'diff-toolbar__expand-button h-7 flex-shrink-0 gap-1 px-1.5 text-muted-foreground hover:text-foreground',
|
||||||
|
showFileSelector && 'ml-auto',
|
||||||
|
)}
|
||||||
title={expandedFiles.size > 0 ? t('diffView.actions.collapseAll') : t('diffView.actions.expandAll')}
|
title={expandedFiles.size > 0 ? t('diffView.actions.collapseAll') : t('diffView.actions.expandAll')}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
name={expandedFiles.size > 0 ? 'arrow-up-s' : 'arrow-down-s'}
|
name="expand-up-down"
|
||||||
className="size-4"
|
className="size-4"
|
||||||
/>
|
/>
|
||||||
<span className="typography-ui-label hidden sm:inline">
|
<span className="diff-toolbar__expand-label typography-ui-label">
|
||||||
{expandedFiles.size > 0 ? t('diffView.actions.collapseAll') : t('diffView.actions.expandAll')}
|
{expandedFiles.size > 0 ? t('diffView.actions.collapseAll') : t('diffView.actions.expandAll')}
|
||||||
</span>
|
</span>
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -857,6 +857,41 @@ html:not(.dark) .chat-scroll {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Diff toolbar: drop low-priority labels as the context panel narrows. */
|
||||||
|
@container diff-toolbar (max-width: 34rem) {
|
||||||
|
.diff-toolbar__file-stats {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@container diff-toolbar (max-width: 40rem) {
|
||||||
|
.diff-toolbar__scope-count,
|
||||||
|
.diff-toolbar__expand-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-toolbar__expand-button {
|
||||||
|
padding-inline: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@container diff-toolbar (max-width: 29rem) {
|
||||||
|
.diff-toolbar__file-label {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-toolbar__file-trigger {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
gap: 0.375rem;
|
||||||
|
padding-inline: 0.625rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diff-toolbar__file-trigger-content {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Status row: collapse optional text when narrow to keep both sides in one line. */
|
/* Status row: collapse optional text when narrow to keep both sides in one line. */
|
||||||
@container status-row (max-width: 30rem) {
|
@container status-row (max-width: 30rem) {
|
||||||
.status-row__active-todo {
|
.status-row__active-todo {
|
||||||
|
|||||||
@@ -953,7 +953,7 @@ export const dict = {
|
|||||||
'gitView.worktree.availableInWorktreeMode': 'Available only in worktree mode',
|
'gitView.worktree.availableInWorktreeMode': 'Available only in worktree mode',
|
||||||
'contextPanel.mode.chat': 'Chat',
|
'contextPanel.mode.chat': 'Chat',
|
||||||
'contextPanel.mode.files': 'Files',
|
'contextPanel.mode.files': 'Files',
|
||||||
'contextPanel.mode.diff': 'Diff',
|
'contextPanel.mode.diff': 'Changes',
|
||||||
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
||||||
'contextPanel.mode.workingDiff': 'Working Diff',
|
'contextPanel.mode.workingDiff': 'Working Diff',
|
||||||
'contextPanel.mode.plan': 'Plan',
|
'contextPanel.mode.plan': 'Plan',
|
||||||
@@ -1202,6 +1202,9 @@ export const dict = {
|
|||||||
'diffView.state.largeDiffDescription': 'Rendering may be slow. You can still view the diff by clicking below.',
|
'diffView.state.largeDiffDescription': 'Rendering may be slow. You can still view the diff by clicking below.',
|
||||||
'diffView.summary.changedFilesSingle': '{count} file changed',
|
'diffView.summary.changedFilesSingle': '{count} file changed',
|
||||||
'diffView.summary.changedFilesPlural': '{count} files changed',
|
'diffView.summary.changedFilesPlural': '{count} files changed',
|
||||||
|
'diffView.scope.changed': 'Changed',
|
||||||
|
'diffView.scope.staged': 'Staged',
|
||||||
|
'diffView.scope.selectorAria': 'Select change mode',
|
||||||
'diffView.actions.retry': 'Retry',
|
'diffView.actions.retry': 'Retry',
|
||||||
'diffView.actions.renderAnyway': 'Render anyway',
|
'diffView.actions.renderAnyway': 'Render anyway',
|
||||||
'diffView.actions.expandAll': 'Expand all',
|
'diffView.actions.expandAll': 'Expand all',
|
||||||
@@ -1298,6 +1301,8 @@ export const dict = {
|
|||||||
'header.services.modelFamily.other': 'Other',
|
'header.services.modelFamily.other': 'Other',
|
||||||
'header.services.shutdownDev': 'Stop OpenChamber',
|
'header.services.shutdownDev': 'Stop OpenChamber',
|
||||||
'header.actions.openPlanAria': 'Open plan',
|
'header.actions.openPlanAria': 'Open plan',
|
||||||
|
'header.actions.toggleChangesPanel': 'Changes panel',
|
||||||
|
'header.actions.toggleChangesPanelAria': 'Toggle changes panel',
|
||||||
'header.actions.planWithShortcut': 'Plan ({shortcut})',
|
'header.actions.planWithShortcut': 'Plan ({shortcut})',
|
||||||
'header.actions.terminalPanelWithShortcut': 'Terminal panel ({shortcut})',
|
'header.actions.terminalPanelWithShortcut': 'Terminal panel ({shortcut})',
|
||||||
'header.actions.toggleTerminalPanelAria': 'Toggle terminal panel',
|
'header.actions.toggleTerminalPanelAria': 'Toggle terminal panel',
|
||||||
|
|||||||
@@ -954,7 +954,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"gitView.worktree.availableInWorktreeMode": "Disponible solo en modo worktree",
|
"gitView.worktree.availableInWorktreeMode": "Disponible solo en modo worktree",
|
||||||
"contextPanel.mode.chat": "Chat",
|
"contextPanel.mode.chat": "Chat",
|
||||||
"contextPanel.mode.files": "Archivos",
|
"contextPanel.mode.files": "Archivos",
|
||||||
"contextPanel.mode.diff": "Diff",
|
"contextPanel.mode.diff": "Cambios",
|
||||||
"contextPanel.mode.stagedDiff": "Staged Diff",
|
"contextPanel.mode.stagedDiff": "Staged Diff",
|
||||||
"contextPanel.mode.workingDiff": "Working Diff",
|
"contextPanel.mode.workingDiff": "Working Diff",
|
||||||
"contextPanel.mode.plan": "Plan",
|
"contextPanel.mode.plan": "Plan",
|
||||||
@@ -1168,6 +1168,9 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"diffView.state.largeDiffDescription": "El renderizado puede ser lento. Aun así puedes ver el diff con el botón de abajo.",
|
"diffView.state.largeDiffDescription": "El renderizado puede ser lento. Aun así puedes ver el diff con el botón de abajo.",
|
||||||
"diffView.summary.changedFilesSingle": "{count} archivo modificado",
|
"diffView.summary.changedFilesSingle": "{count} archivo modificado",
|
||||||
"diffView.summary.changedFilesPlural": "{count} archivos modificados",
|
"diffView.summary.changedFilesPlural": "{count} archivos modificados",
|
||||||
|
"diffView.scope.changed": "Cambiados",
|
||||||
|
"diffView.scope.staged": "Staged",
|
||||||
|
"diffView.scope.selectorAria": "Seleccionar modo de cambios",
|
||||||
"diffView.actions.retry": "Volver a intentar",
|
"diffView.actions.retry": "Volver a intentar",
|
||||||
"diffView.actions.renderAnyway": "Renderizar de todos modos",
|
"diffView.actions.renderAnyway": "Renderizar de todos modos",
|
||||||
"diffView.actions.expandAll": "Expandir todo",
|
"diffView.actions.expandAll": "Expandir todo",
|
||||||
@@ -1264,6 +1267,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"header.services.modelFamily.other": "Otro",
|
"header.services.modelFamily.other": "Otro",
|
||||||
"header.services.shutdownDev": "Detener OpenChamber",
|
"header.services.shutdownDev": "Detener OpenChamber",
|
||||||
"header.actions.openPlanAria": "Abrir plan",
|
"header.actions.openPlanAria": "Abrir plan",
|
||||||
|
"header.actions.toggleChangesPanel": "Panel de cambios",
|
||||||
|
"header.actions.toggleChangesPanelAria": "Alternar panel de cambios",
|
||||||
"header.actions.planWithShortcut": "Plan ({shortcut})",
|
"header.actions.planWithShortcut": "Plan ({shortcut})",
|
||||||
"header.actions.terminalPanelWithShortcut": "Panel de terminal ({shortcut})",
|
"header.actions.terminalPanelWithShortcut": "Panel de terminal ({shortcut})",
|
||||||
"header.actions.toggleTerminalPanelAria": "Mostrar u ocultar panel de terminal",
|
"header.actions.toggleTerminalPanelAria": "Mostrar u ocultar panel de terminal",
|
||||||
|
|||||||
@@ -831,7 +831,7 @@ export const dict = {
|
|||||||
'gitView.worktree.availableInWorktreeMode': 'Disponible uniquement en mode worktree',
|
'gitView.worktree.availableInWorktreeMode': 'Disponible uniquement en mode worktree',
|
||||||
'contextPanel.mode.chat': 'Chat',
|
'contextPanel.mode.chat': 'Chat',
|
||||||
'contextPanel.mode.files': 'Fichiers',
|
'contextPanel.mode.files': 'Fichiers',
|
||||||
'contextPanel.mode.diff': 'Différence',
|
"contextPanel.mode.diff": "Changements",
|
||||||
'contextPanel.mode.stagedDiff': 'Différence par étapes',
|
'contextPanel.mode.stagedDiff': 'Différence par étapes',
|
||||||
'contextPanel.mode.workingDiff': 'Différentiel de travail',
|
'contextPanel.mode.workingDiff': 'Différentiel de travail',
|
||||||
'contextPanel.mode.plan': 'Plan',
|
'contextPanel.mode.plan': 'Plan',
|
||||||
@@ -1075,6 +1075,9 @@ export const dict = {
|
|||||||
'diffView.state.largeDiffDescription': 'Le rendu peut être lent. Vous pouvez tout de même afficher le diff avec le bouton ci-dessous.',
|
'diffView.state.largeDiffDescription': 'Le rendu peut être lent. Vous pouvez tout de même afficher le diff avec le bouton ci-dessous.',
|
||||||
'diffView.summary.changedFilesSingle': 'Le fichier {count} a été modifié',
|
'diffView.summary.changedFilesSingle': 'Le fichier {count} a été modifié',
|
||||||
'diffView.summary.changedFilesPlural': 'Fichiers {count} modifiés',
|
'diffView.summary.changedFilesPlural': 'Fichiers {count} modifiés',
|
||||||
|
"diffView.scope.changed": "Modifiés",
|
||||||
|
"diffView.scope.staged": "Staged",
|
||||||
|
"diffView.scope.selectorAria": "Sélectionner le mode de changements",
|
||||||
'diffView.actions.retry': 'Réessayer',
|
'diffView.actions.retry': 'Réessayer',
|
||||||
'diffView.actions.renderAnyway': 'Afficher quand même',
|
'diffView.actions.renderAnyway': 'Afficher quand même',
|
||||||
'diffView.actions.expandAll': 'Tout développer',
|
'diffView.actions.expandAll': 'Tout développer',
|
||||||
@@ -1164,6 +1167,8 @@ export const dict = {
|
|||||||
'header.services.modelFamily.other': 'Autre',
|
'header.services.modelFamily.other': 'Autre',
|
||||||
'header.services.shutdownDev': 'Arrêter OpenChamber',
|
'header.services.shutdownDev': 'Arrêter OpenChamber',
|
||||||
'header.actions.openPlanAria': 'Plan ouvert',
|
'header.actions.openPlanAria': 'Plan ouvert',
|
||||||
|
"header.actions.toggleChangesPanel": "Panneau des changements",
|
||||||
|
"header.actions.toggleChangesPanelAria": "Basculer le panneau des changements",
|
||||||
'header.actions.planWithShortcut': 'Forfait ({shortcut})',
|
'header.actions.planWithShortcut': 'Forfait ({shortcut})',
|
||||||
'header.actions.terminalPanelWithShortcut': 'Panneau à bornes ({shortcut})',
|
'header.actions.terminalPanelWithShortcut': 'Panneau à bornes ({shortcut})',
|
||||||
'header.actions.toggleTerminalPanelAria': 'Basculer le panneau à bornes',
|
'header.actions.toggleTerminalPanelAria': 'Basculer le panneau à bornes',
|
||||||
|
|||||||
@@ -954,7 +954,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'gitView.worktree.availableInWorktreeMode': '워크트리 모드에서만 사용할 수 있습니다',
|
'gitView.worktree.availableInWorktreeMode': '워크트리 모드에서만 사용할 수 있습니다',
|
||||||
'contextPanel.mode.chat': '채팅',
|
'contextPanel.mode.chat': '채팅',
|
||||||
'contextPanel.mode.files': '파일',
|
'contextPanel.mode.files': '파일',
|
||||||
'contextPanel.mode.diff': '변경사항',
|
"contextPanel.mode.diff": "Changes",
|
||||||
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
||||||
'contextPanel.mode.workingDiff': 'Working Diff',
|
'contextPanel.mode.workingDiff': 'Working Diff',
|
||||||
'contextPanel.mode.plan': '계획',
|
'contextPanel.mode.plan': '계획',
|
||||||
@@ -1205,6 +1205,9 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'diffView.state.largeDiffDescription': '렌더링이 느릴 수 있습니다. 아래 버튼으로 diff를 계속 볼 수 있습니다.',
|
'diffView.state.largeDiffDescription': '렌더링이 느릴 수 있습니다. 아래 버튼으로 diff를 계속 볼 수 있습니다.',
|
||||||
'diffView.summary.changedFilesSingle': '파일 {count}개 변경됨',
|
'diffView.summary.changedFilesSingle': '파일 {count}개 변경됨',
|
||||||
'diffView.summary.changedFilesPlural': '파일 {count}개 변경됨',
|
'diffView.summary.changedFilesPlural': '파일 {count}개 변경됨',
|
||||||
|
"diffView.scope.changed": "Changed",
|
||||||
|
"diffView.scope.staged": "Staged",
|
||||||
|
"diffView.scope.selectorAria": "변경 모드 선택",
|
||||||
'diffView.actions.retry': '다시 시도',
|
'diffView.actions.retry': '다시 시도',
|
||||||
'diffView.actions.renderAnyway': '그래도 렌더링',
|
'diffView.actions.renderAnyway': '그래도 렌더링',
|
||||||
'diffView.actions.expandAll': '모두 펼치기',
|
'diffView.actions.expandAll': '모두 펼치기',
|
||||||
@@ -1300,6 +1303,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'header.services.remaining': '남은 양',
|
'header.services.remaining': '남은 양',
|
||||||
'header.services.modelFamily.other': '기타',
|
'header.services.modelFamily.other': '기타',
|
||||||
'header.actions.openPlanAria': '플랜 열기',
|
'header.actions.openPlanAria': '플랜 열기',
|
||||||
|
"header.actions.toggleChangesPanel": "변경 패널",
|
||||||
|
"header.actions.toggleChangesPanelAria": "변경 패널 전환",
|
||||||
'header.actions.planWithShortcut': '플랜 ({shortcut})',
|
'header.actions.planWithShortcut': '플랜 ({shortcut})',
|
||||||
'header.actions.terminalPanelWithShortcut': '터미널 패널 ({shortcut})',
|
'header.actions.terminalPanelWithShortcut': '터미널 패널 ({shortcut})',
|
||||||
'header.actions.toggleTerminalPanelAria': '토글 터미널 패널',
|
'header.actions.toggleTerminalPanelAria': '토글 터미널 패널',
|
||||||
|
|||||||
@@ -1244,7 +1244,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'contextPanel.iframe.sessionChatTitle': 'Czat sesji {sessionID}',
|
'contextPanel.iframe.sessionChatTitle': 'Czat sesji {sessionID}',
|
||||||
'contextPanel.mode.chat': 'Chat',
|
'contextPanel.mode.chat': 'Chat',
|
||||||
'contextPanel.mode.context': 'Context',
|
'contextPanel.mode.context': 'Context',
|
||||||
'contextPanel.mode.diff': 'Różnice',
|
"contextPanel.mode.diff": "Zmiany",
|
||||||
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
||||||
'contextPanel.mode.workingDiff': 'Working Diff',
|
'contextPanel.mode.workingDiff': 'Working Diff',
|
||||||
'contextPanel.mode.files': 'Pliki',
|
'contextPanel.mode.files': 'Pliki',
|
||||||
@@ -1440,6 +1440,9 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'diffView.state.notGitRepository': 'To nie jest repozytorium Git. Użyj karty Git, aby zainicjować lub zmienić katalog.',
|
'diffView.state.notGitRepository': 'To nie jest repozytorium Git. Użyj karty Git, aby zainicjować lub zmienić katalog.',
|
||||||
'diffView.state.selectSessionDirectory': 'Wybierz katalog sesji, aby zobaczyć diffy',
|
'diffView.state.selectSessionDirectory': 'Wybierz katalog sesji, aby zobaczyć diffy',
|
||||||
'diffView.summary.changedFilesPlural': 'Zmieniono {count} plików',
|
'diffView.summary.changedFilesPlural': 'Zmieniono {count} plików',
|
||||||
|
"diffView.scope.changed": "Zmienione",
|
||||||
|
"diffView.scope.staged": "Staged",
|
||||||
|
"diffView.scope.selectorAria": "Wybierz tryb zmian",
|
||||||
'diffView.summary.changedFilesSingle': 'Zmieniono {count} plik',
|
'diffView.summary.changedFilesSingle': 'Zmieniono {count} plik',
|
||||||
'directoryExplorerDialog.actions.addProject': 'Dodaj projekt',
|
'directoryExplorerDialog.actions.addProject': 'Dodaj projekt',
|
||||||
'directoryExplorerDialog.actions.addLocalProject': 'Dodaj projekt lokalny',
|
'directoryExplorerDialog.actions.addLocalProject': 'Dodaj projekt lokalny',
|
||||||
@@ -1950,6 +1953,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'header.actions.newSessionAria': 'Nowa sesja',
|
'header.actions.newSessionAria': 'Nowa sesja',
|
||||||
'header.actions.newSessionWithShortcut': 'Nowa sesja ({shortcut})',
|
'header.actions.newSessionWithShortcut': 'Nowa sesja ({shortcut})',
|
||||||
'header.actions.openPlanAria': 'Otwórz plan',
|
'header.actions.openPlanAria': 'Otwórz plan',
|
||||||
|
"header.actions.toggleChangesPanel": "Panel zmian",
|
||||||
|
"header.actions.toggleChangesPanelAria": "Przełącz panel zmian",
|
||||||
'header.actions.openSessionsAria': 'Otwórz sesje',
|
'header.actions.openSessionsAria': 'Otwórz sesje',
|
||||||
'header.actions.openAppMenu': 'Menu OpenChamber',
|
'header.actions.openAppMenu': 'Menu OpenChamber',
|
||||||
'header.actions.openAppMenuAria': 'Otwórz menu OpenChamber',
|
'header.actions.openAppMenuAria': 'Otwórz menu OpenChamber',
|
||||||
|
|||||||
@@ -954,7 +954,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"gitView.worktree.availableInWorktreeMode": "Disponível apenas em modo worktree",
|
"gitView.worktree.availableInWorktreeMode": "Disponível apenas em modo worktree",
|
||||||
"contextPanel.mode.chat": "Chat",
|
"contextPanel.mode.chat": "Chat",
|
||||||
"contextPanel.mode.files": "Arquivos",
|
"contextPanel.mode.files": "Arquivos",
|
||||||
"contextPanel.mode.diff": "Diff",
|
"contextPanel.mode.diff": "Alterações",
|
||||||
"contextPanel.mode.stagedDiff": "Staged Diff",
|
"contextPanel.mode.stagedDiff": "Staged Diff",
|
||||||
"contextPanel.mode.workingDiff": "Working Diff",
|
"contextPanel.mode.workingDiff": "Working Diff",
|
||||||
"contextPanel.mode.plan": "Plano",
|
"contextPanel.mode.plan": "Plano",
|
||||||
@@ -1168,6 +1168,9 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"diffView.state.largeDiffDescription": "A renderização pode ser lenta. Você ainda pode ver o diff pelo botão abaixo.",
|
"diffView.state.largeDiffDescription": "A renderização pode ser lenta. Você ainda pode ver o diff pelo botão abaixo.",
|
||||||
"diffView.summary.changedFilesSingle": "{count} arquivo modificado",
|
"diffView.summary.changedFilesSingle": "{count} arquivo modificado",
|
||||||
"diffView.summary.changedFilesPlural": "{count} arquivos modificados",
|
"diffView.summary.changedFilesPlural": "{count} arquivos modificados",
|
||||||
|
"diffView.scope.changed": "Alteradas",
|
||||||
|
"diffView.scope.staged": "Staged",
|
||||||
|
"diffView.scope.selectorAria": "Selecionar modo de alterações",
|
||||||
"diffView.actions.retry": "Tentar novamente",
|
"diffView.actions.retry": "Tentar novamente",
|
||||||
"diffView.actions.renderAnyway": "Renderizar mesmo assim",
|
"diffView.actions.renderAnyway": "Renderizar mesmo assim",
|
||||||
"diffView.actions.expandAll": "Expandir tudo",
|
"diffView.actions.expandAll": "Expandir tudo",
|
||||||
@@ -1264,6 +1267,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"header.services.modelFamily.other": "Outro",
|
"header.services.modelFamily.other": "Outro",
|
||||||
"header.services.shutdownDev": "Parar OpenChamber",
|
"header.services.shutdownDev": "Parar OpenChamber",
|
||||||
"header.actions.openPlanAria": "Abrir plano",
|
"header.actions.openPlanAria": "Abrir plano",
|
||||||
|
"header.actions.toggleChangesPanel": "Painel de alterações",
|
||||||
|
"header.actions.toggleChangesPanelAria": "Alternar painel de alterações",
|
||||||
"header.actions.planWithShortcut": "Plano ({shortcut})",
|
"header.actions.planWithShortcut": "Plano ({shortcut})",
|
||||||
"header.actions.terminalPanelWithShortcut": "Painel de terminal ({shortcut})",
|
"header.actions.terminalPanelWithShortcut": "Painel de terminal ({shortcut})",
|
||||||
"header.actions.toggleTerminalPanelAria": "Mostrar ou ocultar painel de terminal",
|
"header.actions.toggleTerminalPanelAria": "Mostrar ou ocultar painel de terminal",
|
||||||
|
|||||||
@@ -954,7 +954,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"gitView.worktree.availableInWorktreeMode": "Доступно лише в режимі worktree",
|
"gitView.worktree.availableInWorktreeMode": "Доступно лише в режимі worktree",
|
||||||
"contextPanel.mode.chat": "Чат",
|
"contextPanel.mode.chat": "Чат",
|
||||||
"contextPanel.mode.files": "Файли",
|
"contextPanel.mode.files": "Файли",
|
||||||
"contextPanel.mode.diff": "Diff",
|
"contextPanel.mode.diff": "Зміни",
|
||||||
"contextPanel.mode.stagedDiff": "Staged Diff",
|
"contextPanel.mode.stagedDiff": "Staged Diff",
|
||||||
"contextPanel.mode.workingDiff": "Working Diff",
|
"contextPanel.mode.workingDiff": "Working Diff",
|
||||||
"contextPanel.mode.plan": "План",
|
"contextPanel.mode.plan": "План",
|
||||||
@@ -1168,6 +1168,9 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"diffView.state.largeDiffDescription": "Рендеринг може бути повільним. Ви все одно можете переглянути diff кнопкою нижче.",
|
"diffView.state.largeDiffDescription": "Рендеринг може бути повільним. Ви все одно можете переглянути diff кнопкою нижче.",
|
||||||
"diffView.summary.changedFilesSingle": "Змінено файл: {count}",
|
"diffView.summary.changedFilesSingle": "Змінено файл: {count}",
|
||||||
"diffView.summary.changedFilesPlural": "Змінено файлів: {count}",
|
"diffView.summary.changedFilesPlural": "Змінено файлів: {count}",
|
||||||
|
"diffView.scope.changed": "Змінені",
|
||||||
|
"diffView.scope.staged": "Індексовані",
|
||||||
|
"diffView.scope.selectorAria": "Вибрати режим змін",
|
||||||
"diffView.actions.retry": "Повторити спробу",
|
"diffView.actions.retry": "Повторити спробу",
|
||||||
"diffView.actions.renderAnyway": "Все одно відрендерити",
|
"diffView.actions.renderAnyway": "Все одно відрендерити",
|
||||||
"diffView.actions.expandAll": "Розгорнути все",
|
"diffView.actions.expandAll": "Розгорнути все",
|
||||||
@@ -1264,6 +1267,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
"header.services.shutdownDev": "Зупинити OpenChamber",
|
"header.services.shutdownDev": "Зупинити OpenChamber",
|
||||||
"header.services.modelFamily.other": "інше",
|
"header.services.modelFamily.other": "інше",
|
||||||
"header.actions.openPlanAria": "Відкрити план",
|
"header.actions.openPlanAria": "Відкрити план",
|
||||||
|
"header.actions.toggleChangesPanel": "Панель змін",
|
||||||
|
"header.actions.toggleChangesPanelAria": "Перемкнути панель змін",
|
||||||
"header.actions.planWithShortcut": "План ({shortcut})",
|
"header.actions.planWithShortcut": "План ({shortcut})",
|
||||||
"header.actions.terminalPanelWithShortcut": "Термінальна панель ({shortcut})",
|
"header.actions.terminalPanelWithShortcut": "Термінальна панель ({shortcut})",
|
||||||
"header.actions.toggleTerminalPanelAria": "Перемкнути панель терміналу",
|
"header.actions.toggleTerminalPanelAria": "Перемкнути панель терміналу",
|
||||||
|
|||||||
@@ -954,7 +954,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'gitView.worktree.availableInWorktreeMode': '仅在工作树模式下可用',
|
'gitView.worktree.availableInWorktreeMode': '仅在工作树模式下可用',
|
||||||
'contextPanel.mode.chat': '聊天',
|
'contextPanel.mode.chat': '聊天',
|
||||||
'contextPanel.mode.files': '文件',
|
'contextPanel.mode.files': '文件',
|
||||||
'contextPanel.mode.diff': '差异',
|
"contextPanel.mode.diff": "更改",
|
||||||
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
||||||
'contextPanel.mode.workingDiff': 'Working Diff',
|
'contextPanel.mode.workingDiff': 'Working Diff',
|
||||||
'contextPanel.mode.plan': '计划',
|
'contextPanel.mode.plan': '计划',
|
||||||
@@ -1168,6 +1168,9 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'diffView.state.largeDiffDescription': '渲染可能较慢。你仍可点击下方按钮查看差异。',
|
'diffView.state.largeDiffDescription': '渲染可能较慢。你仍可点击下方按钮查看差异。',
|
||||||
'diffView.summary.changedFilesSingle': '{count} 个文件已变更',
|
'diffView.summary.changedFilesSingle': '{count} 个文件已变更',
|
||||||
'diffView.summary.changedFilesPlural': '{count} 个文件已变更',
|
'diffView.summary.changedFilesPlural': '{count} 个文件已变更',
|
||||||
|
"diffView.scope.changed": "已更改",
|
||||||
|
"diffView.scope.staged": "已暂存",
|
||||||
|
"diffView.scope.selectorAria": "选择更改模式",
|
||||||
'diffView.actions.retry': '重试',
|
'diffView.actions.retry': '重试',
|
||||||
'diffView.actions.renderAnyway': '仍然渲染',
|
'diffView.actions.renderAnyway': '仍然渲染',
|
||||||
'diffView.actions.expandAll': '全部展开',
|
'diffView.actions.expandAll': '全部展开',
|
||||||
@@ -1264,6 +1267,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'header.services.shutdownDev': '停止 OpenChamber',
|
'header.services.shutdownDev': '停止 OpenChamber',
|
||||||
'header.services.modelFamily.other': '其他',
|
'header.services.modelFamily.other': '其他',
|
||||||
'header.actions.openPlanAria': '打开计划',
|
'header.actions.openPlanAria': '打开计划',
|
||||||
|
"header.actions.toggleChangesPanel": "更改面板",
|
||||||
|
"header.actions.toggleChangesPanelAria": "切换更改面板",
|
||||||
'header.actions.planWithShortcut': '计划({shortcut})',
|
'header.actions.planWithShortcut': '计划({shortcut})',
|
||||||
'header.actions.terminalPanelWithShortcut': '终端面板({shortcut})',
|
'header.actions.terminalPanelWithShortcut': '终端面板({shortcut})',
|
||||||
'header.actions.toggleTerminalPanelAria': '切换终端面板',
|
'header.actions.toggleTerminalPanelAria': '切换终端面板',
|
||||||
|
|||||||
@@ -966,7 +966,7 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'gitView.worktree.availableInWorktreeMode': '僅在 worktree 模式可用',
|
'gitView.worktree.availableInWorktreeMode': '僅在 worktree 模式可用',
|
||||||
'contextPanel.mode.chat': '聊天',
|
'contextPanel.mode.chat': '聊天',
|
||||||
'contextPanel.mode.files': '檔案',
|
'contextPanel.mode.files': '檔案',
|
||||||
'contextPanel.mode.diff': '差異',
|
"contextPanel.mode.diff": "變更",
|
||||||
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
'contextPanel.mode.stagedDiff': 'Staged Diff',
|
||||||
'contextPanel.mode.workingDiff': 'Working Diff',
|
'contextPanel.mode.workingDiff': 'Working Diff',
|
||||||
'contextPanel.mode.plan': '計畫',
|
'contextPanel.mode.plan': '計畫',
|
||||||
@@ -1178,6 +1178,9 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'diffView.state.largeDiffDescription': '渲染可能較慢。你仍可點擊下方按鈕查看差異。',
|
'diffView.state.largeDiffDescription': '渲染可能較慢。你仍可點擊下方按鈕查看差異。',
|
||||||
'diffView.summary.changedFilesSingle': '{count} 個檔案已變更',
|
'diffView.summary.changedFilesSingle': '{count} 個檔案已變更',
|
||||||
'diffView.summary.changedFilesPlural': '{count} 個檔案已變更',
|
'diffView.summary.changedFilesPlural': '{count} 個檔案已變更',
|
||||||
|
"diffView.scope.changed": "已變更",
|
||||||
|
"diffView.scope.staged": "已暫存",
|
||||||
|
"diffView.scope.selectorAria": "選擇變更模式",
|
||||||
'diffView.actions.retry': '重試',
|
'diffView.actions.retry': '重試',
|
||||||
'diffView.actions.renderAnyway': '仍然渲染',
|
'diffView.actions.renderAnyway': '仍然渲染',
|
||||||
'diffView.actions.expandAll': '全部展開',
|
'diffView.actions.expandAll': '全部展開',
|
||||||
@@ -1268,6 +1271,8 @@ export const dict: Record<I18nKey, string> = {
|
|||||||
'header.services.shutdownDev': '停止 OpenChamber',
|
'header.services.shutdownDev': '停止 OpenChamber',
|
||||||
'header.services.modelFamily.other': '其他',
|
'header.services.modelFamily.other': '其他',
|
||||||
'header.actions.openPlanAria': '開啟計畫',
|
'header.actions.openPlanAria': '開啟計畫',
|
||||||
|
"header.actions.toggleChangesPanel": "變更面板",
|
||||||
|
"header.actions.toggleChangesPanelAria": "切換變更面板",
|
||||||
'header.actions.planWithShortcut': '計畫({shortcut})',
|
'header.actions.planWithShortcut': '計畫({shortcut})',
|
||||||
'header.actions.terminalPanelWithShortcut': '終端機面板({shortcut})',
|
'header.actions.terminalPanelWithShortcut': '終端機面板({shortcut})',
|
||||||
'header.actions.toggleTerminalPanelAria': '切換終端機面板',
|
'header.actions.toggleTerminalPanelAria': '切換終端機面板',
|
||||||
|
|||||||
@@ -191,6 +191,10 @@ const normalizeContextPanelTabDedupeKey = (
|
|||||||
targetPath: string | null,
|
targetPath: string | null,
|
||||||
dedupeKey: string | null | undefined,
|
dedupeKey: string | null | undefined,
|
||||||
): string => {
|
): string => {
|
||||||
|
if (mode === 'diff') {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof dedupeKey === 'string') {
|
if (typeof dedupeKey === 'string') {
|
||||||
const trimmed = dedupeKey.trim();
|
const trimmed = dedupeKey.trim();
|
||||||
if (trimmed) {
|
if (trimmed) {
|
||||||
@@ -1032,7 +1036,6 @@ export const useUIStore = create<UIStore>()(
|
|||||||
get().openContextPanelTab(normalizedDirectory, {
|
get().openContextPanelTab(normalizedDirectory, {
|
||||||
mode: 'diff',
|
mode: 'diff',
|
||||||
targetPath: normalizedFilePath,
|
targetPath: normalizedFilePath,
|
||||||
dedupeKey: staged ? 'staged' : null,
|
|
||||||
stagedDiff: staged,
|
stagedDiff: staged,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user