perf: reduce re-renders, fix mobile keyboard handling, add chunk load recovery, and improve PATH management (#1028)
* fix: exclude file content from reverted prompt text Revert and fork now restore only the user's original prompt, not server-injected file content Uses existing isSyntheticPart helper for type-safe filtering * fix: keep scrollbar visible when hovering over thumb * fix: prevent ESC abort from triggering when terminal is focused * fix: pass directory to permission/question reply calls so approvals actually resolve * fix: default model selection not responding after Base UI migration * fix: prevent modal content from shifting and clipping footer buttons * fix: improve session switching performance and add sub-agent export with prompt collapse Defer viewport anchor saving to eliminate ~800ms UI freeze when switching sessions Add export dialog to include sub-agent tasks recursively in markdown export Add collapse chevron button for expanded user prompts in sticky header * fix: resolve sidebar scroll and TDZ crash in session sidebar * perf: reduce CPU overhead and re-renders across chat, layout, and settings * fix: position collapse button at top of message and prevent ESC abort in terminal * fix: position collapse button at top and add padding only when expanded * refactor: extract shared PATH utilities and mobile keyboard hook * refactor: import shared path-utils in electron, use module-level style constants - Electron now imports pathLooksUserConfigured/mergePathValues from shared path-utils.js instead of inline duplication - ToolPart collapsedCustomStyle moved from useMemo([]) to module const * fix: resolve remaining merge conflicts and type errors - Remove duplicate variable declarations in SessionNodeItem - Remove orphaned export callback body from conflict resolution - Fix HelpDialog description -> descriptionKey (i18n rename) * fix: resolve type-check and lint errors in session-actions.test.ts - Added missing bun:test type declarations (beforeEach, mock, mock.module) - Removed unused State import - Replaced 'as any' casts with proper OpencodeClient and ChildStoreManager types - Added eslint-disable for unused _ parameter in mock function * fix PR 1028 export and PATH edge cases * fix startup retry exhaustion state * remove opencode package lock change * fix sub-session rename cancellation --------- Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
Bohdan Triapitsyn
parent
632e6cc97b
commit
4523e9c486
@@ -758,17 +758,8 @@ const ToolScrollableTextOutput: React.FC<{
|
||||
style={syntaxTheme}
|
||||
language={outputLanguage}
|
||||
PreTag="div"
|
||||
customStyle={{
|
||||
...toolDisplayStyles.getCollapsedStyles(),
|
||||
padding: 0,
|
||||
overflow: 'visible',
|
||||
}}
|
||||
codeTagProps={{
|
||||
style: {
|
||||
background: 'transparent',
|
||||
backgroundColor: 'transparent',
|
||||
},
|
||||
}}
|
||||
customStyle={TOOL_COLLAPSED_CUSTOM_STYLE}
|
||||
codeTagProps={CODE_TAG_PROPS}
|
||||
wrapLongLines
|
||||
>
|
||||
{renderedOutput}
|
||||
@@ -1233,6 +1224,19 @@ const TOOL_DIFF_METRICS = {
|
||||
fileGap: 0,
|
||||
};
|
||||
|
||||
const TOOL_COLLAPSED_CUSTOM_STYLE: React.CSSProperties = {
|
||||
...toolDisplayStyles.getCollapsedStyles(),
|
||||
padding: 0,
|
||||
overflow: 'visible',
|
||||
};
|
||||
|
||||
const CODE_TAG_PROPS = { style: { background: 'transparent', backgroundColor: 'transparent' } };
|
||||
|
||||
const TOOL_ERROR_ICON_STYLE: React.CSSProperties = { color: 'var(--status-error)' };
|
||||
const TOOL_NORMAL_ICON_STYLE: React.CSSProperties = { color: 'var(--tools-icon)' };
|
||||
const TOOL_ERROR_TITLE_STYLE: React.CSSProperties = { color: 'var(--status-error)' };
|
||||
const TOOL_NORMAL_TITLE_STYLE: React.CSSProperties = { color: 'var(--tools-title)' };
|
||||
|
||||
type DiffPatchEntry = {
|
||||
id: string;
|
||||
title: string;
|
||||
@@ -1370,24 +1374,29 @@ const getDiffPatchEntries = (
|
||||
};
|
||||
|
||||
const DiffPreview: React.FC<DiffPreviewProps> = React.memo(({ diff, pierreTheme, pierreThemeType, diffViewMode }) => {
|
||||
const options = React.useMemo(
|
||||
() => ({
|
||||
diffStyle: diffViewMode === 'side-by-side' ? 'split' as const : 'unified' as const,
|
||||
diffIndicators: 'none' as const,
|
||||
hunkSeparators: 'line-info-basic' as const,
|
||||
lineDiffType: 'none' as const,
|
||||
disableFileHeader: true,
|
||||
maxLineDiffLength: 1000,
|
||||
expansionLineCount: 20,
|
||||
overflow: 'wrap' as const,
|
||||
theme: pierreTheme,
|
||||
themeType: pierreThemeType,
|
||||
unsafeCSS: TOOL_DIFF_UNSAFE_CSS,
|
||||
}),
|
||||
[diffViewMode, pierreTheme, pierreThemeType]
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="typography-code px-1 pb-1 pt-0">
|
||||
<PatchDiff
|
||||
patch={diff}
|
||||
metrics={TOOL_DIFF_METRICS}
|
||||
options={{
|
||||
diffStyle: diffViewMode === 'side-by-side' ? 'split' : 'unified',
|
||||
diffIndicators: 'none',
|
||||
hunkSeparators: 'line-info-basic',
|
||||
lineDiffType: 'none',
|
||||
disableFileHeader: true,
|
||||
maxLineDiffLength: 1000,
|
||||
expansionLineCount: 20,
|
||||
overflow: 'wrap',
|
||||
theme: pierreTheme,
|
||||
themeType: pierreThemeType,
|
||||
unsafeCSS: TOOL_DIFF_UNSAFE_CSS,
|
||||
}}
|
||||
options={options}
|
||||
className="block w-full"
|
||||
/>
|
||||
</div>
|
||||
@@ -1797,14 +1806,17 @@ const ToolPart: React.FC<ToolPartProps> = ({
|
||||
|
||||
const shouldNotifyStructuralChange = isFinalized || isTaskTool;
|
||||
|
||||
const onContentChangeRef = React.useRef(onContentChange);
|
||||
onContentChangeRef.current = onContentChange;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!shouldNotifyStructuralChange) {
|
||||
return;
|
||||
}
|
||||
if (typeof isExpanded === 'boolean') {
|
||||
onContentChange?.('structural');
|
||||
onContentChangeRef.current?.('structural');
|
||||
}
|
||||
}, [isExpanded, onContentChange, shouldNotifyStructuralChange]);
|
||||
}, [isExpanded, shouldNotifyStructuralChange]);
|
||||
|
||||
const stateWithData = state as ToolStateWithMetadata;
|
||||
const metadata = stateWithData.metadata;
|
||||
@@ -2425,6 +2437,9 @@ const ToolPart: React.FC<ToolPartProps> = ({
|
||||
handleMainClick(event);
|
||||
};
|
||||
|
||||
const iconStyle = !isTaskTool && isError ? TOOL_ERROR_ICON_STYLE : TOOL_NORMAL_ICON_STYLE;
|
||||
const titleStyle = !isTaskTool && isError ? TOOL_ERROR_TITLE_STYLE : TOOL_NORMAL_TITLE_STYLE;
|
||||
|
||||
if (!shouldTreatAsFinalized && !isActive && !isTaskTool) {
|
||||
return null;
|
||||
}
|
||||
@@ -2455,7 +2470,7 @@ const ToolPart: React.FC<ToolPartProps> = ({
|
||||
isExpanded && 'opacity-0',
|
||||
!isExpanded && 'group-hover/tool:opacity-0'
|
||||
)}
|
||||
style={!isTaskTool && isError ? { color: 'var(--status-error)' } : { color: 'var(--tools-icon)' }}
|
||||
style={iconStyle}
|
||||
>
|
||||
{getToolIcon(normalizedPartTool || part.tool)}
|
||||
</div>
|
||||
@@ -2476,7 +2491,7 @@ const ToolPart: React.FC<ToolPartProps> = ({
|
||||
active={Boolean(isActive && !isError)}
|
||||
minDurationMs={300}
|
||||
className="typography-meta font-medium flex-shrink-0"
|
||||
style={!isTaskTool && isError ? { color: 'var(--status-error)' } : { color: 'var(--tools-title)' }}
|
||||
style={titleStyle}
|
||||
title={displayName}
|
||||
>
|
||||
{displayName}
|
||||
@@ -2490,7 +2505,7 @@ const ToolPart: React.FC<ToolPartProps> = ({
|
||||
active={Boolean(isActive && !isError)}
|
||||
minDurationMs={300}
|
||||
className="typography-meta font-medium flex-shrink-0"
|
||||
style={!isTaskTool && isError ? { color: 'var(--status-error)' } : { color: 'var(--tools-title)' }}
|
||||
style={titleStyle}
|
||||
title={displayName}
|
||||
>
|
||||
{displayName}
|
||||
|
||||
Reference in New Issue
Block a user