From eca8a60640623aab679088bb4572f2f7ebe75a23 Mon Sep 17 00:00:00 2001 From: NB2030 Date: Tue, 31 Mar 2026 15:40:28 +0300 Subject: [PATCH] Make the home page navigation sidebar collapsible --- .../HomePage/HomePageMenuBar.js | 79 +++++++++++++++---- .../Preferences/PreferencesContext.js | 4 + .../Preferences/PreferencesProvider.js | 17 ++++ 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/newIDE/app/src/MainFrame/EditorContainers/HomePage/HomePageMenuBar.js b/newIDE/app/src/MainFrame/EditorContainers/HomePage/HomePageMenuBar.js index 57d14d0f4ffb..df0a379ac847 100644 --- a/newIDE/app/src/MainFrame/EditorContainers/HomePage/HomePageMenuBar.js +++ b/newIDE/app/src/MainFrame/EditorContainers/HomePage/HomePageMenuBar.js @@ -1,9 +1,10 @@ // @flow import * as React from 'react'; -import { Trans } from '@lingui/macro'; +import { t, Trans } from '@lingui/macro'; import { Column, marginsSize } from '../../../UI/Grid'; import { useResponsiveWindowSize } from '../../../UI/Responsive/ResponsiveWindowMeasurer'; import IconButton from '../../../UI/IconButton'; +import DoubleChevronArrowLeft from '../../../UI/CustomSvgIcons/DoubleChevronArrowLeft'; import DoubleChevronArrowRight from '../../../UI/CustomSvgIcons/DoubleChevronArrowRight'; import VerticalTabButton, { verticalTabButtonSize, @@ -21,6 +22,7 @@ import { Toolbar, ToolbarGroup } from '../../../UI/Toolbar'; import AuthenticatedUserContext from '../../../Profile/AuthenticatedUserContext'; import { SECTION_DESKTOP_SPACING } from './SectionContainer'; import Text from '../../../UI/Text'; +import PreferencesContext from '../../Preferences/PreferencesContext'; const iconSize = 24; const iconButtonPadding = 4; @@ -46,6 +48,8 @@ export const styles = { minWidth: homepageDesktopMenuBarWidth, display: 'flex', flexDirection: 'column', + position: 'relative', + overflow: 'visible', }, mobileMenu: { paddingTop: 10, @@ -77,6 +81,19 @@ export const styles = { justifyContent: 'center', marginBottom: 2, }, + collapseButton: { + position: 'absolute', + top: SECTION_DESKTOP_SPACING + 4, + right: 0, + transform: 'translateX(50%)', + zIndex: 1, + backgroundColor: 'var(--theme-paper-background-dark)', + border: '1px solid var(--theme-home-separator-color)', + borderRadius: 999, + }, + desktopTabsColumn: { + paddingTop: 22, + }, }; type Props = {| @@ -98,7 +115,13 @@ const HomePageMenuBar = ({ const isMobileOrSmallScreen = isMobile || isMediumScreen; const gdevelopTheme = React.useContext(GDevelopThemeContext); const { limits } = React.useContext(AuthenticatedUserContext); + const preferences = React.useContext(PreferencesContext); + const isMenuCollapsed = preferences.values.homePageMenuIsCollapsed; const tabsToDisplay = getTabsToDisplay({ limits }); + const shouldHideLabels = isMobileOrSmallScreen || isMenuCollapsed; + const menuWidth = shouldHideLabels + ? homepageMediumMenuBarWidth + : homepageDesktopMenuBarWidth; const largeScreenOnlyButtons: { label: React.Node, getIcon: GetIconFunction, @@ -191,28 +214,56 @@ const HomePageMenuBar = ({ - {isMobileOrSmallScreen && ( + {isMobileOrSmallScreen ? ( + ) : ( + + preferences.setHomePageMenuIsCollapsed(!isMenuCollapsed) + } + size="small" + style={{ + ...styles.collapseButton, + backgroundColor: gdevelopTheme.home.header.backgroundColor, + border: `1px solid ${gdevelopTheme.home.separator.color}`, + }} + tooltip={ + isMenuCollapsed ? t`Expand navigation` : t`Collapse navigation` + } + > + {isMenuCollapsed ? ( + + ) : ( + + )} + )} - {tabsToDisplay.map(({ label, tab, getIcon, id }) => ( - setActiveTab(tab)} - getIcon={getIcon} - isActive={activeTab === tab} - hideLabel={isMobileOrSmallScreen} - id={id} - /> - ))} + + {tabsToDisplay.map(({ label, tab, getIcon, id }) => ( + setActiveTab(tab)} + getIcon={getIcon} + isActive={activeTab === tab} + hideLabel={shouldHideLabels} + id={id} + /> + ))} +
@@ -224,7 +275,7 @@ const HomePageMenuBar = ({ onClick={onClick} getIcon={getIcon} isActive={false} - hideLabel={isMobileOrSmallScreen} + hideLabel={shouldHideLabels} id={id} /> ))} diff --git a/newIDE/app/src/MainFrame/Preferences/PreferencesContext.js b/newIDE/app/src/MainFrame/Preferences/PreferencesContext.js index 9771a5593846..93a1eaa66cbc 100644 --- a/newIDE/app/src/MainFrame/Preferences/PreferencesContext.js +++ b/newIDE/app/src/MainFrame/Preferences/PreferencesContext.js @@ -244,6 +244,7 @@ export type PreferencesValues = {| useBackgroundSerializerForSaving: boolean, disableNpmScriptConfirmation: boolean, showJsTypeError: boolean, + homePageMenuIsCollapsed: boolean, |}; /** @@ -367,6 +368,7 @@ export type Preferences = {| setAutomaticallyUseCreditsForAiRequests: (enabled: boolean) => void, setUseBackgroundSerializerForSaving: (enabled: boolean) => void, setShowJsTypeError: (enabled: boolean) => void, + setHomePageMenuIsCollapsed: (collapsed: boolean) => void, |}; export const initialPreferences = { @@ -432,6 +434,7 @@ export const initialPreferences = { useBackgroundSerializerForSaving: false, disableNpmScriptConfirmation: false, showJsTypeError: false, + homePageMenuIsCollapsed: false, }, setMultipleValues: () => {}, setLanguage: () => {}, @@ -518,6 +521,7 @@ export const initialPreferences = { setAutomaticallyUseCreditsForAiRequests: (enabled: boolean) => {}, setUseBackgroundSerializerForSaving: (enabled: boolean) => {}, setShowJsTypeError: (enabled: boolean) => {}, + setHomePageMenuIsCollapsed: (collapsed: boolean) => {}, }; const PreferencesContext: React.Context = React.createContext( diff --git a/newIDE/app/src/MainFrame/Preferences/PreferencesProvider.js b/newIDE/app/src/MainFrame/Preferences/PreferencesProvider.js index fb0314db42c5..f1c20de5ff7e 100644 --- a/newIDE/app/src/MainFrame/Preferences/PreferencesProvider.js +++ b/newIDE/app/src/MainFrame/Preferences/PreferencesProvider.js @@ -137,6 +137,7 @@ export const getInitialPreferences = (): { useShortcutToClosePreviewWindow: boolean, userShortcutMap: {}, watchProjectFolderFilesForLocalProjects: boolean, + homePageMenuIsCollapsed: boolean, } => { let languageOrLocale = 'en'; const browserLanguageOrLocale = getBrowserLanguageOrLocale(); @@ -399,6 +400,10 @@ export default class PreferencesProvider extends React.Component { ): any), // $FlowFixMe[method-unbinding] setShowJsTypeError: (this._setShowJsTypeError.bind(this): any), + // $FlowFixMe[method-unbinding] + setHomePageMenuIsCollapsed: (this._setHomePageMenuIsCollapsed.bind( + this + ): any), }; componentDidMount() { @@ -1379,6 +1384,18 @@ export default class PreferencesProvider extends React.Component { ); } + _setHomePageMenuIsCollapsed(homePageMenuIsCollapsed: boolean) { + this.setState( + state => ({ + values: { + ...state.values, + homePageMenuIsCollapsed, + }, + }), + () => this._persistValuesToLocalStorage(this.state) + ); + } + render(): any { return (