app: Replace local/session docs toggle with state.

Having this persist across sessions is not necessary and a bit overly complicated when we add more sideview states such as camera (which should not stay on by default).
This commit is contained in:
Laurens Valk
2026-03-30 14:37:59 +02:00
parent 7e4a9b94d5
commit 38a71238f9
3 changed files with 12 additions and 54 deletions
+2 -10
View File
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2021-2023 The Pybricks Authors
// Copyright (c) 2021-2026 The Pybricks Authors
import { cleanup } from '@testing-library/react';
import React from 'react';
@@ -42,15 +42,7 @@ it.each([false, true])('should render', (darkMode) => {
});
describe('documentation pane', () => {
it('should show by default on large screens', () => {
jest.spyOn(window, 'innerWidth', 'get').mockReturnValue(1024);
testRender(<App />);
expect(document.querySelector('.pb-show-docs')).not.toBeNull();
expect(document.querySelector('.pb-hide-docs')).toBeNull();
});
it('should hide by default on small screens', () => {
jest.spyOn(window, 'innerWidth', 'get').mockReturnValue(800);
it('should hide by default', () => {
testRender(<App />);
expect(document.querySelector('.pb-show-docs')).toBeNull();
expect(document.querySelector('.pb-hide-docs')).not.toBeNull();
+10 -6
View File
@@ -6,13 +6,14 @@ import './app.scss';
import { Button, Classes, Spinner } from '@blueprintjs/core';
import { Manual } from '@blueprintjs/icons';
import React, { useEffect, useState } from 'react';
type SideView = 'off' | 'docs';
import SplitterLayout from 'react-splitter-layout';
import { useLocalStorage, useTernaryDarkMode } from 'usehooks-ts';
import Activities from '../activities/Activities';
import DfuWindowsDriverInstallDialog from '../firmware/dfuWindowsDriverInstallDialog/DfuWindowsDriverInstallDialog';
import { InstallPybricksDialog } from '../firmware/installPybricksDialog/InstallPybricksDialog';
import RestoreOfficialDialog from '../firmware/restoreOfficialDialog/RestoreOfficialDialog';
import { useSettingIsShowDocsEnabled } from '../settings/hooks';
import SponsorDialog from '../sponsor/SponsorDialog';
import StatusBar from '../status-bar/StatusBar';
import Toolbar from '../toolbar/Toolbar';
@@ -72,8 +73,7 @@ const Docs: React.FunctionComponent = () => {
const App: React.FunctionComponent = () => {
const i18n = useI18n();
const { isDarkMode } = useTernaryDarkMode();
const { isSettingShowDocsEnabled, toggleIsSettingShowDocsEnabled } =
useSettingIsShowDocsEnabled();
const [sideView, setSideView] = useState<SideView>('off');
const [isDragging, setIsDragging] = useState(false);
const [docsSplit, setDocsSplit] = useLocalStorage('app-docs-split', 30);
@@ -118,7 +118,7 @@ const App: React.FunctionComponent = () => {
<div className="pb-app-main" style={{ position: 'relative' }}>
<SplitterLayout
customClassName={
isSettingShowDocsEnabled ? 'pb-show-docs' : 'pb-hide-docs'
sideView === 'docs' ? 'pb-show-docs' : 'pb-hide-docs'
}
onDragStart={(): void => setIsDragging(true)}
onDragEnd={(): void => setIsDragging(false)}
@@ -148,11 +148,15 @@ const App: React.FunctionComponent = () => {
large
icon={<Manual />}
title={
isSettingShowDocsEnabled
sideView === 'docs'
? i18n.translate('docs.hide')
: i18n.translate('docs.show')
}
onClick={toggleIsSettingShowDocsEnabled}
onClick={() =>
setSideView(
sideView === 'docs' ? 'off' : 'docs',
)
}
/>
</main>
<aside
-38
View File
@@ -1,38 +0,0 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors
import { useCallback, useEffect } from 'react';
import { useEffectOnce, useLocalStorage, useSessionStorage } from 'usehooks-ts';
/** Hook for "showDocs" setting. */
export function useSettingIsShowDocsEnabled(): {
isSettingShowDocsEnabled: boolean;
setIsSettingShowDocsEnabled: (value: boolean) => void;
toggleIsSettingShowDocsEnabled: () => void;
} {
const [isLastSettingShowDocsEnabled, setIsLastSettingShowDocsEnabled] =
useLocalStorage('setting.showDocs', window.innerWidth >= 1024);
const [isSettingShowDocsEnabled, setIsSettingShowDocsEnabled] = useSessionStorage(
'setting.showDocs',
isLastSettingShowDocsEnabled,
);
// Force writing to session storage since default value is not constant.
useEffectOnce(() => setIsSettingShowDocsEnabled(isSettingShowDocsEnabled));
useEffect(() => {
setIsLastSettingShowDocsEnabled(isSettingShowDocsEnabled);
}, [isSettingShowDocsEnabled, setIsLastSettingShowDocsEnabled]);
const toggleIsSettingShowDocsEnabled = useCallback(
() => setIsSettingShowDocsEnabled((x) => !x),
[setIsSettingShowDocsEnabled],
);
return {
isSettingShowDocsEnabled,
setIsSettingShowDocsEnabled,
toggleIsSettingShowDocsEnabled,
};
}