Yuki Takei 5 лет назад
Родитель
Сommit
308c0b19c0

+ 7 - 3
src/client/js/components/Navbar/PersonalDropdown.jsx

@@ -25,6 +25,10 @@ const PersonalDropdown = (props) => {
     window.location.href = '/logout';
   };
 
+  const preferDrawerModeSwitchModifiedHandler = (bool) => {
+    appContainer.setDrawerModePreference(bool);
+  };
+
   const followOsCheckboxModifiedHandler = (bool) => {
     // reset user preference
     if (bool) {
@@ -44,7 +48,7 @@ const PersonalDropdown = (props) => {
   /*
    * render
    */
-  const { preferDarkModeByMediaQuery, preferDarkModeByUser } = appContainer.state;
+  const { preferDarkModeByMediaQuery, preferDarkModeByUser, preferDrawerModeByUser } = appContainer.state;
   const isUserPreferenceExists = preferDarkModeByUser != null;
   const isDarkMode = () => {
     if (isUserPreferenceExists) {
@@ -95,8 +99,8 @@ const PersonalDropdown = (props) => {
                   id="swSidebarMode"
                   className="custom-control-input"
                   type="checkbox"
-                  // checked={}
-                  // onChange={}
+                  checked={preferDrawerModeByUser}
+                  onChange={e => preferDrawerModeSwitchModifiedHandler(!e.target.checked)}
                 />
                 <label className="custom-control-label" htmlFor="swSidebarMode"></label>
               </div>

+ 35 - 13
src/client/js/components/Sidebar.jsx

@@ -26,6 +26,7 @@ class Sidebar extends React.Component {
   };
 
   state = {
+    isDrawerMode: this.props.appContainer.state.preferDrowerModeByUser,
     currentContentsId: 'recent',
   };
 
@@ -56,12 +57,11 @@ class Sidebar extends React.Component {
     const mdOrAvobeHandler = (mql) => {
       // sm -> md
       if (mql.matches) {
-        appContainer.setState({ isDrawerOpened: false });
-        navigationUIController.enableResize();
-
-        // restore width
-        if (this.sidebarWidthCached != null) {
-          navigationUIController.setState({ productNavWidth: this.sidebarWidthCached });
+        if (appContainer.state.preferDrowerModeByUser) {
+          this.toggleDrawerMode(true);
+        }
+        else {
+          this.toggleDrawerMode(false);
         }
       }
       // md -> sm
@@ -69,18 +69,39 @@ class Sidebar extends React.Component {
         // cache width
         this.sidebarWidthCached = navigationUIController.state.productNavWidth;
 
-        appContainer.setState({ isDrawerOpened: false });
-        navigationUIController.disableResize();
-        navigationUIController.expand();
-
-        // fix width
-        navigationUIController.setState({ productNavWidth: sidebarDefaultWidth });
+        this.toggleDrawerMode(true);
       }
     };
 
     appContainer.addBreakpointListener('md', mdOrAvobeHandler, true);
   }
 
+  toggleDrawerMode(bool) {
+    const { appContainer, navigationUIController } = this.props;
+
+    this.setState({ isDrawerMode: bool });
+
+    // Drawer
+    if (bool) {
+      appContainer.setState({ isDrawerOpened: false });
+      navigationUIController.disableResize();
+      navigationUIController.expand();
+
+      // fix width
+      navigationUIController.setState({ productNavWidth: sidebarDefaultWidth });
+    }
+    // Dock
+    else {
+      appContainer.setState({ isDrawerOpened: false });
+      navigationUIController.enableResize();
+
+      // restore width
+      if (this.sidebarWidthCached != null) {
+        navigationUIController.setState({ productNavWidth: this.sidebarWidthCached });
+      }
+    }
+  }
+
   backdropClickedHandler = () => {
     const { appContainer } = this.props;
     appContainer.setState({ isDrawerOpened: false });
@@ -118,11 +139,12 @@ class Sidebar extends React.Component {
   }
 
   render() {
+    const { isDrawerMode } = this.state;
     const { isDrawerOpened } = this.props.appContainer.state;
 
     return (
       <>
-        <div className={`grw-sidebar ${isDrawerOpened ? 'open' : ''}`}>
+        <div className={`grw-sidebar ${isDrawerMode ? 'grw-sidebar-drawer' : ''} ${isDrawerOpened ? 'open' : ''}`}>
           <ThemeProvider
             theme={theme => ({
               ...theme,

+ 22 - 1
src/client/js/services/AppContainer.js

@@ -35,7 +35,7 @@ export default class AppContainer extends Container {
       editorMode: null,
       preferDarkModeByMediaQuery: false,
       preferDarkModeByUser: null,
-      breakpoint: 'xs',
+      preferDrowerModeByUser: null,
       isDrawerOpened: false,
 
       isPageCreateModalShown: false,
@@ -111,10 +111,19 @@ export default class AppContainer extends Container {
   }
 
   init() {
+    this.initSidebarMode();
     this.initColorScheme();
     this.initPlugins();
   }
 
+  async initSidebarMode() {
+    // initialize: restore settings from localStorage
+    const { localStorage } = window;
+    if (localStorage.preferDrowerModeByUser != null) {
+      await this.setState({ preferDrowerModeByUser: localStorage.preferDrowerModeByUser === 'true' });
+    }
+  }
+
   async initColorScheme() {
     const switchStateByMediaQuery = async(mql) => {
       const preferDarkMode = mql.matches;
@@ -386,6 +395,18 @@ export default class AppContainer extends Container {
     targetComponent.launchDrawioModal(beginLineNumber, endLineNumber);
   }
 
+  /**
+   * Set Sidebar mode preference by user
+   * @param {boolean} preferDockMode
+   */
+  async setDrawerModePreference(preferDrawerMode) {
+    this.setState({ preferDrowerModeByUser: preferDrawerMode });
+
+    // store settings to localStorage
+    const { localStorage } = window;
+    localStorage.preferDrowerModeByUser = preferDrawerMode;
+  }
+
   /**
    * Set color scheme preference by user
    * @param {boolean} isDarkMode

+ 27 - 29
src/client/styles/scss/_sidebar.scss

@@ -117,42 +117,40 @@
 }
 
 // Drawer Mode
-@include media-breakpoint-down(sm) {
-  .grw-sidebar {
-    position: fixed;
-    z-index: $zindex-fixed - 2;
-
-    // override @atlaskit/navigation-next styles
-    div[data-layout-container='true'] {
-      // css-teprsg
-      > div:nth-of-type(2) {
-        display: none;
-      }
-    }
-    div[data-testid='Navigation'] {
-      // css-xxx-Outer
-      > div:nth-of-type(2) {
-        display: none;
-      }
-    }
+.grw-sidebar.grw-sidebar-drawer {
+  position: fixed;
+  z-index: $zindex-fixed - 2;
 
-    &:not(.open) {
-      div[data-testid='Navigation'] {
-        left: -#{$grw-sidebar-nav-width + $grw-sidebar-content-min-width};
-      }
+  // override @atlaskit/navigation-next styles
+  div[data-layout-container='true'] {
+    // css-teprsg
+    > div:nth-of-type(2) {
+      display: none;
     }
-    &.open {
-      div[data-testid='Navigation'] {
-        left: 0;
-      }
+  }
+  div[data-testid='Navigation'] {
+    // css-xxx-Outer
+    > div:nth-of-type(2) {
+      display: none;
     }
+  }
 
+  &:not(.open) {
+    div[data-testid='Navigation'] {
+      left: -#{$grw-sidebar-nav-width + $grw-sidebar-content-min-width};
+    }
+  }
+  &.open {
     div[data-testid='Navigation'] {
-      transition: left 300ms cubic-bezier(0.25, 1, 0.5, 1);
+      left: 0;
     }
   }
 
-  .grw-sidebar-backdrop.modal-backdrop {
-    z-index: $zindex-fixed - 4;
+  div[data-testid='Navigation'] {
+    transition: left 300ms cubic-bezier(0.25, 1, 0.5, 1);
   }
 }
+
+.grw-sidebar-backdrop.modal-backdrop {
+  z-index: $zindex-fixed - 4;
+}