From e76ba866bbcd6b091c6663131e2fd9039d0d22d6 Mon Sep 17 00:00:00 2001 From: Linda Paiste Date: Mon, 31 Jul 2023 15:41:40 -0500 Subject: [PATCH 1/2] Create selector functions for files. --- client/components/Nav.jsx | 3 ++- client/modules/IDE/components/Editor.jsx | 6 ++---- client/modules/IDE/components/Sidebar.jsx | 5 ++--- client/modules/IDE/pages/IDEView.jsx | 6 ++---- client/modules/IDE/pages/MobileIDEView.jsx | 6 ++---- client/modules/IDE/selectors/files.js | 15 +++++++++++++++ client/modules/Mobile/MobileSketchView.jsx | 8 ++------ 7 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 client/modules/IDE/selectors/files.js diff --git a/client/components/Nav.jsx b/client/components/Nav.jsx index 6e6a350d5e..06f3d8497b 100644 --- a/client/components/Nav.jsx +++ b/client/components/Nav.jsx @@ -12,6 +12,7 @@ import { setAllAccessibleOutput, setLanguage } from '../modules/IDE/actions/preferences'; +import { selectRootFile } from '../modules/IDE/selectors/files'; import { logoutUser } from '../modules/User/actions'; import getConfig from '../utils/getConfig'; @@ -403,7 +404,7 @@ function mapStateToProps(state) { project: state.project, user: state.user, unsavedChanges: state.ide.unsavedChanges, - rootFile: state.files.filter((file) => file.name === 'root')[0], + rootFile: selectRootFile(state), language: state.preferences.language, isUserOwner: getIsUserOwner(state), editorLink: selectSketchPath(state) diff --git a/client/modules/IDE/components/Editor.jsx b/client/modules/IDE/components/Editor.jsx index e07c16b1a0..f5e963363a 100644 --- a/client/modules/IDE/components/Editor.jsx +++ b/client/modules/IDE/components/Editor.jsx @@ -44,6 +44,7 @@ import '../../../utils/htmlmixed'; import '../../../utils/p5-javascript'; import Timer from '../components/Timer'; import EditorAccessibility from '../components/EditorAccessibility'; +import { selectActiveFile } from '../selectors/files'; import AssetPreview from './AssetPreview'; import { metaKey } from '../../../utils/metaKey'; import './show-hint'; @@ -601,10 +602,7 @@ Editor.propTypes = { function mapStateToProps(state) { return { files: state.files, - file: - state.files.find((file) => file.isSelectedFile) || - state.files.find((file) => file.name === 'sketch.js') || - state.files.find((file) => file.name !== 'root'), + file: selectActiveFile(state), htmlFile: getHTMLFile(state.files), ide: state.ide, preferences: state.preferences, diff --git a/client/modules/IDE/components/Sidebar.jsx b/client/modules/IDE/components/Sidebar.jsx index 3e92fd8436..b28a2fba4d 100644 --- a/client/modules/IDE/components/Sidebar.jsx +++ b/client/modules/IDE/components/Sidebar.jsx @@ -9,6 +9,7 @@ import { openProjectOptions, openUploadFileModal } from '../actions/ide'; +import { selectRootFile } from '../selectors/files'; import { getAuthenticated, selectCanEditSketch } from '../selectors/users'; import ConnectedFileNode from './FileNode'; @@ -23,9 +24,7 @@ export default function SideBar() { const [isFocused, setIsFocused] = useState(false); - const files = useSelector((state) => state.files); - // TODO: use `selectRootFile` defined in another PR - const rootFile = files.filter((file) => file.name === 'root')[0]; + const rootFile = useSelector(selectRootFile); const projectOptionsVisible = useSelector( (state) => state.ide.projectOptionsVisible ); diff --git a/client/modules/IDE/pages/IDEView.jsx b/client/modules/IDE/pages/IDEView.jsx index 685dc3fd5b..f61c176630 100644 --- a/client/modules/IDE/pages/IDEView.jsx +++ b/client/modules/IDE/pages/IDEView.jsx @@ -33,6 +33,7 @@ import About from '../components/About'; import AddToCollectionList from '../components/AddToCollectionList'; import Feedback from '../components/Feedback'; import { CollectionSearchbar } from '../components/Searchbar'; +import { selectActiveFile } from '../selectors/files'; import { getIsUserOwner } from '../selectors/users'; import RootPage from '../../../components/RootPage'; @@ -549,10 +550,7 @@ IDEView.propTypes = { function mapStateToProps(state) { return { - selectedFile: - state.files.find((file) => file.isSelectedFile) || - state.files.find((file) => file.name === 'sketch.js') || - state.files.find((file) => file.name !== 'root'), + selectedFile: selectActiveFile(state), htmlFile: getHTMLFile(state.files), ide: state.ide, preferences: state.preferences, diff --git a/client/modules/IDE/pages/MobileIDEView.jsx b/client/modules/IDE/pages/MobileIDEView.jsx index 6442a0adba..1a7eb3600d 100644 --- a/client/modules/IDE/pages/MobileIDEView.jsx +++ b/client/modules/IDE/pages/MobileIDEView.jsx @@ -41,6 +41,7 @@ import { remSize } from '../../../theme'; import ActionStrip from '../../../components/mobile/ActionStrip'; import useAsModal from '../../../components/useAsModal'; import Dropdown from '../../../components/Dropdown'; +import { selectActiveFile } from '../selectors/files'; import { getIsUserOwner } from '../selectors/users'; import { @@ -475,10 +476,7 @@ MobileIDEView.propTypes = { function mapStateToProps(state) { return { - selectedFile: - state.files.find((file) => file.isSelectedFile) || - state.files.find((file) => file.name === 'sketch.js') || - state.files.find((file) => file.name !== 'root'), + selectedFile: selectActiveFile(state), ide: state.ide, files: state.files, unsavedChanges: state.ide.unsavedChanges, diff --git a/client/modules/IDE/selectors/files.js b/client/modules/IDE/selectors/files.js new file mode 100644 index 0000000000..e2044b6d89 --- /dev/null +++ b/client/modules/IDE/selectors/files.js @@ -0,0 +1,15 @@ +import { createSelector } from 'reselect'; + +const selectFiles = (state) => state.files; + +export const selectRootFile = createSelector(selectFiles, (files) => + files.find((file) => file.name === 'root') +); + +export const selectActiveFile = createSelector( + selectFiles, + (files) => + files.find((file) => file.isSelectedFile) || + files.find((file) => file.name === 'sketch.js') || + files.find((file) => file.name !== 'root') +); diff --git a/client/modules/Mobile/MobileSketchView.jsx b/client/modules/Mobile/MobileSketchView.jsx index dc69550f6f..3cbb8ebb78 100644 --- a/client/modules/Mobile/MobileSketchView.jsx +++ b/client/modules/Mobile/MobileSketchView.jsx @@ -16,6 +16,7 @@ import { getHTMLFile } from '../IDE/reducers/files'; import { ExitIcon } from '../../common/icons'; import Footer from '../../components/mobile/Footer'; +import { selectActiveFile } from '../IDE/selectors/files'; import Content from './MobileViewContent'; const MobileSketchView = () => { @@ -23,12 +24,7 @@ const MobileSketchView = () => { const htmlFile = useSelector((state) => getHTMLFile(state.files)); const projectName = useSelector((state) => state.project.name); - const selectedFile = useSelector( - (state) => - state.files.find((file) => file.isSelectedFile) || - state.files.find((file) => file.name === 'sketch.js') || - state.files.find((file) => file.name !== 'root') - ); + const selectedFile = useSelector(selectActiveFile); const { setTextOutput, From e63cb03f3f4e9e1872d8ee6d933c38d11ca772b2 Mon Sep 17 00:00:00 2001 From: Linda Paiste Date: Thu, 10 Aug 2023 20:02:28 -0500 Subject: [PATCH 2/2] Use `selectRootFile` in Nav. --- client/modules/IDE/components/Header/Nav.jsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/client/modules/IDE/components/Header/Nav.jsx b/client/modules/IDE/components/Header/Nav.jsx index 3750033aaa..37709945c4 100644 --- a/client/modules/IDE/components/Header/Nav.jsx +++ b/client/modules/IDE/components/Header/Nav.jsx @@ -14,6 +14,7 @@ import { setLanguage } from '../../actions/preferences'; import NavBar from '../../../../components/Nav/NavBar'; import CaretLeftIcon from '../../../../images/left-arrow.svg'; import LogoIcon from '../../../../images/p5js-logo-small.svg'; +import { selectRootFile } from '../../selectors/files'; import { selectSketchPath } from '../../selectors/project'; import { metaKey, metaKeyName } from '../../../../utils/metaKey'; import { useSketchActions } from '../../hooks'; @@ -102,17 +103,14 @@ const DashboardMenu = () => { ); }; -const ProjectMenu = (props) => { +const ProjectMenu = () => { const isUserOwner = useSelector(getIsUserOwner); const project = useSelector((state) => state.project); const user = useSelector((state) => state.user); const isUnsaved = !project?.id; - // TODO: use selectRootFile selector - const rootFile = useSelector( - (state) => state.files.filter((file) => file.name === 'root')[0] - ); + const rootFile = useSelector(selectRootFile); const cmRef = useContext(CmControllerContext);