Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

split pane changes #829

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/client/RunCodeWidget/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { OverlayTrigger, Tooltip } from '../bootstrap';
import './style.scss';

// Feature flag for split pane feature (WIP)
const enableSplitPane = false;
const enableSplitPane = true;

export const RunCodeWidget = ({
runCodeWidgetTooltipText = (
Expand Down
44 changes: 39 additions & 5 deletions src/client/VZCodeContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
import { useURLSync } from './useURLSync';
import { useKeyboardShortcuts } from './useKeyboardShortcuts';
import { useRunCode } from './useRunCode';
import { findPane } from './vzReducer/findPane';

// This context centralizes all the "smart" logic
// to do with the application state. This includes
Expand Down Expand Up @@ -240,12 +241,41 @@ export const VZCodeProvider = ({
} = state;

// TODO support splitPane type
if (pane.type !== 'leafPane') {
throw new Error('Expected leafPane');
// Determine the active pane and handle both leaf and non-leaf panes
let activePaneId = state.activePaneId;
let activePane = findPane(pane, activePaneId);

let tabList = [];
let activeFileId = null;

if (activePane.type === 'leafPane') {
tabList = activePane.tabList;
activeFileId = activePane.activeFileId;
} else {
// Handle non-leaf pane logic if needed
// For now, just log the active pane for debugging purposes
console.log('Active Pane is not a leafPane:', activePane);
// check if any children are leaf panes
// if so, set the active pane to the first leaf pane
// if no children are leaf panes check if any childrens children are leaf panes
// if so, set the active pane to the first leaf pane
while (activePane.type !== 'leafPane') {
// check if any children are leaf panes
for (const child of activePane.children) {
if (child.type === 'leafPane') {
activePaneId = child.id;
activePane = child;
break;
}
}
// if no children are leaf panes check if any childrens children are leaf panes
if (activePane.type !== 'leafPane') {
// set the active pane to the first child
activePaneId = activePane.children[0].id;
activePane = activePane.children[0];
}
}
}
const tabList = pane.tabList;
const activeFileId = pane.activeFileId;

// Functions for dispatching actions to the reducer.
const {
setActiveFileId,
Expand All @@ -270,6 +300,10 @@ export const VZCodeProvider = ({
} = useActions(dispatch);

// Sync tab state to the URL.
// TODO make the URL sync to the active pane only
// const activePaneId = state.activePaneId;
// // find the active pane
// const activePane = findPane(pane, activePaneId);
useURLSync({
content,
openTab,
Expand Down
106 changes: 27 additions & 79 deletions src/client/useURLSync.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,20 @@
import { useSearchParams } from 'react-router-dom';
import { FileId, TabState, VZCodeContent } from '../types';
import { useEffect, useMemo, useRef } from 'react';
import {
TabStateParams,
decodeTabs,
encodeTabs,
} from './tabsSearchParameters';
import { FileId, VZCodeContent } from '../types';
import { useEffect, useRef } from 'react';

// Synchronizes the tab state with the URL parameters.
// Synchronizes the active pane state with the URL parameters.
export const useURLSync = ({
content,
openTab,
setActiveFileId,
tabList,
activeFileId,
}: {
content: VZCodeContent | null;
openTab: (tabState: TabState) => void;
setActiveFileId: (activeFileId: FileId) => void;
tabList: Array<TabState>;
activeFileId: FileId | null;
}) => {
// Use React router to get and set the search parameters.
// Use React router to get and set the search parameters.
const [searchParams, setSearchParams] = useSearchParams();

// Extract the tab state parameters from the search parameters.
const tabStateParams: TabStateParams = useMemo(
() => ({
file: searchParams.get('file'),
tabs: searchParams.get('tabs'),
}),
[searchParams],
);

// `true` after the state is updated based on the
// initial search parameters from the URL.
const isInitialized = useRef(false);
Expand All @@ -49,25 +31,15 @@ export const useURLSync = ({
return;
}

// Decode the search parameters.
const { tabList, activeFileId } = decodeTabs({
tabStateParams,
content,
});
// Get the active file id from the search parameters.
const file = searchParams.get('file');
if (file) {
setActiveFileId(file as FileId);
}

// Mark the state as initialized.
isInitialized.current = true;

// Update the state.
tabList.forEach(openTab);
setActiveFileId(activeFileId);
}, [
content,
searchParams,
setActiveFileId,
openTab,
isInitialized,
]);
}, [content, searchParams, setActiveFileId, isInitialized]);

// Track content in a ref so that we can use it in the
// effect below without triggering the effect when
Expand All @@ -77,60 +49,36 @@ export const useURLSync = ({
contentRef.current = content;
}, [content]);

// track setSearchParams in a ref so that we can use it in the
// Track setSearchParams in a ref so that we can use it in the
// effect below without triggering the effect on each render.
// The definition of `setSearchParams` changes on every render.
const setSearchParamsRef = useRef(setSearchParams);
useEffect(() => {
setSearchParamsRef.current = setSearchParams;
}, [setSearchParams]);

// Update the URL to match the current state whenever
// the active file or tab list changes.
// the active file changes.
useEffect(() => {
// Safety check to make sure the content is loaded.
// Should never happen.
if (!contentRef.current) {
return;
}

const newTabStateParams: TabStateParams = encodeTabs({
tabList,
activeFileId,
content: contentRef.current,
});

// Update the URL if the search parameters have changed.
setSearchParamsRef.current(
(oldSearchParams: URLSearchParams) => {
// Create a copy of the old search params
const updatedSearchParams = new URLSearchParams(
oldSearchParams,
);
// Update the URL if the active file has changed.
setSearchParamsRef.current((oldSearchParams: URLSearchParams) => {
// Create a copy of the old search params
const updatedSearchParams = new URLSearchParams(oldSearchParams);

// Set the 'file' parameter
if (newTabStateParams.file) {
updatedSearchParams.set(
'file',
newTabStateParams.file,
);
} else {
updatedSearchParams.delete('file'); // Remove 'file' if it's not present in newTabStateParams
}
// Set the 'file' parameter
if (activeFileId) {
updatedSearchParams.set('file', activeFileId);
} else {
updatedSearchParams.delete('file'); // Remove 'file' if there's no active file
}

// Set the 'tabs' parameter
if (newTabStateParams.tabs) {
updatedSearchParams.set(
'tabs',
newTabStateParams.tabs,
);
} else {
updatedSearchParams.delete('tabs'); // Remove 'tabs' if it's not present in newTabStateParams
}

// Return the updated search params
return updatedSearchParams;
},
);
}, [tabList, activeFileId]);
};
// Return the updated search params
return updatedSearchParams;
});
}, [activeFileId]);
};
2 changes: 2 additions & 0 deletions src/client/vzReducer/splitCurrentPaneReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ export const splitCurrentPaneReducer = (
const newLeafPane1: Pane = {
id: `${activePaneId}-1`, // Generate unique IDs for new panes
type: 'leafPane',
// TODO Copy the tab list from the active pane
tabList: [],
activeFileId: null,
};

const newLeafPane2: Pane = {
id: `${activePaneId}-2`,
type: 'leafPane',
// TODO Copy the tab list from the active pane
tabList: [],
activeFileId: null,
};
Expand Down
3 changes: 2 additions & 1 deletion test/sampleDirectories/kitchenSink/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</head>
<body></body>
<script>
let
let a = 10;
le
</script>
</html>