Skip to content

Commit 429e5cf

Browse files
Michael Remediakismeta-codesync[bot]
authored andcommitted
Auto-switch commit info panel position with sidebar mode
Summary: When the user toggles "Show ISL in Sidebar" in VS Code settings, the commit info panel position now updates automatically: - Sidebar ON → panel moves to bottom (horizontal space is limited) - Sidebar OFF → panel moves to right (default editor panel layout) The VS Code extension also focuses the correct view after switching: sidebar mode focuses the sidebar view, panel mode opens and focuses a new editor panel. Additionally fixes a pre-existing crash in MinHeightTextField where the component asserted `ref` must be an object, but callers could omit it (ref is optional). The assert now allows `undefined`. Reviewed By: evangrayk Differential Revision: D100022486 fbshipit-source-id: db11d3e88f9401f55f63a49326a1349538799567
1 parent 1e568d4 commit 429e5cf

File tree

6 files changed

+49
-11
lines changed

6 files changed

+49
-11
lines changed

addons/isl/src/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {TopBar} from './TopBar';
2727
import {TopLevelAlerts} from './TopLevelAlert';
2828
import {TopLevelErrors} from './TopLevelErrors';
2929
import {tracker} from './analytics';
30-
import {commitInfoLocationAtom, islDrawerState} from './drawerState';
30+
import {effectiveCommitInfoLocationAtom, islDrawerState} from './drawerState';
3131
import {t, T} from './i18n';
3232
import platform from './platform';
3333
import {useMainContentWidth} from './responsive';
@@ -89,7 +89,7 @@ function NullStateOrDrawers() {
8989

9090
function ISLDrawers() {
9191
const setDrawerState = useSetAtom(islDrawerState);
92-
const location = useAtomValue(commitInfoLocationAtom);
92+
const location = useAtomValue(effectiveCommitInfoLocationAtom);
9393
useCommand('ToggleSidebar', () => {
9494
setDrawerState(state => ({
9595
...state,

addons/isl/src/CommitInfoView/MinHeightTextField.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export function MinHeightTextField(
2929
const {onInput, keepNewlines, className, ref, ...rest} = props;
3030

3131
// ref could also be a callback ref; don't bother supporting that right now.
32-
assert(typeof ref === 'object', 'MinHeightTextArea requires ref object');
32+
assert(ref == null || typeof ref === 'object', 'MinHeightTextArea requires ref object');
3333

3434
// whenever the value is changed, recompute & apply the minimum height
3535
useEffect(() => {

addons/isl/src/SettingsTooltip.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import {
4646
overrideDisabledSubmitModes,
4747
} from './codeReview/github/branchPrState';
4848
import {debugToolsEnabledState} from './debug/DebugToolsState';
49-
import {commitInfoLocationAtom, type CommitInfoLocation} from './drawerState';
49+
import {commitInfoLocationAtom, type CommitInfoLocationWithAuto} from './drawerState';
5050
import {externalMergeToolAtom} from './externalMergeTool';
5151
import {t, T} from './i18n';
5252
import {configBackedAtom, readAtom} from './jotaiUtils';
@@ -290,19 +290,24 @@ function RenderCompactSetting() {
290290
function CommitInfoLocationSetting() {
291291
const [location, setLocation] = useAtom(commitInfoLocationAtom);
292292
return (
293-
<Tooltip title={t('Position of the Commit Info panel relative to the commit graph')}>
293+
<Tooltip
294+
title={t(
295+
'Position of the Commit Info panel relative to the commit graph. ' +
296+
'"Auto" uses bottom in narrow mode (e.g. sidebar) and right otherwise.',
297+
)}>
294298
<div className="dropdown-container setting-inline-dropdown">
295299
<T>Commit Info Panel</T>
296-
<Dropdown<{value: CommitInfoLocation; name: string}>
300+
<Dropdown<{value: CommitInfoLocationWithAuto; name: string}>
297301
data-testid="commit-info-location-setting"
298302
value={location}
299303
options={[
304+
{value: 'auto', name: t('Auto')},
300305
{value: 'right', name: t('Right')},
301306
{value: 'bottom', name: t('Bottom')},
302307
{value: 'left', name: t('Left')},
303308
{value: 'top', name: t('Top')},
304309
]}
305-
onChange={event => setLocation(event.currentTarget.value as CommitInfoLocation)}
310+
onChange={event => setLocation(event.currentTarget.value as CommitInfoLocationWithAuto)}
306311
/>
307312
</div>
308313
</Tooltip>

addons/isl/src/drawerState.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,39 @@
77

88
import type {AllDrawersState, DrawerState} from './Drawers';
99

10+
import {atom} from 'jotai';
1011
import {localStorageBackedAtom, readAtom, writeAtom} from './jotaiUtils';
12+
import {isNarrowWindow} from './responsive';
1113
import {getWindowWidthInPixels, registerCleanup} from './utils';
1214

1315
const AUTO_CLOSE_MAX_SIZE = 700;
1416
const DEFAULT_RIGHT_DRAWER_WIDTH = 500;
1517

1618
export type CommitInfoLocation = 'right' | 'bottom' | 'left' | 'top';
19+
export type CommitInfoLocationWithAuto = CommitInfoLocation | 'auto';
1720

18-
export const commitInfoLocationAtom = localStorageBackedAtom<CommitInfoLocation>(
21+
export const commitInfoLocationAtom = localStorageBackedAtom<CommitInfoLocationWithAuto>(
1922
'isl.commit-info-location',
20-
'right',
23+
'auto',
2124
);
2225

26+
/**
27+
* Resolves 'auto' to a concrete location based on window width.
28+
* When 'auto', uses 'bottom' in narrow windows and 'right' otherwise.
29+
* Uses window width (not main content width) to avoid oscillation —
30+
* changing drawer position affects main content width but not window width.
31+
*/
32+
export const effectiveCommitInfoLocationAtom = atom<CommitInfoLocation>(get => {
33+
const preference = get(commitInfoLocationAtom);
34+
if (preference === 'auto') {
35+
return get(isNarrowWindow) ? 'bottom' : 'right';
36+
}
37+
return preference;
38+
});
39+
2340
/** Expand the commit info drawer at the current configured location. */
2441
export function expandCommitInfoView() {
25-
const loc = readAtom(commitInfoLocationAtom);
42+
const loc = readAtom(effectiveCommitInfoLocationAtom);
2643
writeAtom(islDrawerState, val => ({...val, [loc]: {...val[loc], collapsed: false}}));
2744
}
2845

@@ -45,7 +62,7 @@ function autoCloseBasedOnWindowWidth() {
4562
return;
4663
}
4764

48-
const location = readAtom(commitInfoLocationAtom);
65+
const location = readAtom(effectiveCommitInfoLocationAtom);
4966
const isVertical = location === 'top' || location === 'bottom';
5067
if (isVertical) {
5168
// Only auto-close for horizontal (left/right) drawers based on window width.

addons/isl/src/responsive.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,17 @@ export const isNarrowCommitTree = atom(
6767
get(mainContentWidthState) <
6868
(get(renderCompactAtom) ? NARROW_COMMIT_TREE_WIDTH_WHEN_COMPACT : NARROW_COMMIT_TREE_WIDTH),
6969
);
70+
71+
/**
72+
* Tracks the window/viewport width. Unlike mainContentWidthState, this is
73+
* stable regardless of drawer position changes, making it safe for layout
74+
* decisions that affect drawer placement (avoids oscillation).
75+
*/
76+
export const windowWidthState = atom(window.innerWidth);
77+
windowWidthState.onMount = set => {
78+
const listener = () => set(window.innerWidth);
79+
window.addEventListener('resize', listener);
80+
return () => window.removeEventListener('resize', listener);
81+
};
82+
83+
export const isNarrowWindow = atom(get => get(windowWidthState) < NARROW_COMMIT_TREE_WIDTH);

addons/vscode/extension/islWebviewPanel.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,13 @@ export function registerISLCommands(
364364
if (islPanelOrViewResult && isPanel(islPanelOrViewResult.panel)) {
365365
islPanelOrViewResult.panel.dispose();
366366
}
367+
executeVSCodeCommand('sapling.isl.focus');
367368
} else {
368369
// Switching to panel mode: clear the view reference so a new panel can be created
369370
if (islPanelOrViewResult && !isPanel(islPanelOrViewResult.panel)) {
370371
islPanelOrViewResult = undefined;
371372
}
373+
createOrFocusISLWebview(context, platform, logger);
372374
}
373375
}
374376
}),

0 commit comments

Comments
 (0)