mirror of
https://github.com/pybricks/pybricks-code.git
synced 2026-09-15 11:04:49 +00:00
move docs toggle to settings
This commit is contained in:
@@ -1,30 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2020 The Pybricks Authors
|
||||
// File: sagas/app.ts
|
||||
// Manages the application lifecycle.
|
||||
|
||||
import { put, select, takeEvery } from 'redux-saga/effects';
|
||||
import {
|
||||
AppActionType,
|
||||
AppStartupAction,
|
||||
AppToggleDocsAction,
|
||||
toggleDocs,
|
||||
} from '../actions/app';
|
||||
import { RootState } from '../reducers';
|
||||
|
||||
function* handleStartup(_action: AppStartupAction): Generator {
|
||||
const showDocs = localStorage.getItem('showDocs');
|
||||
if (showDocs === null ? window.innerWidth >= 1024 : showDocs === 'true') {
|
||||
yield put(toggleDocs());
|
||||
}
|
||||
}
|
||||
|
||||
function* storeDocsState(_action: AppToggleDocsAction): Generator {
|
||||
const showDocs = (yield select((s: RootState) => s.app.showDocs)) as boolean;
|
||||
localStorage.setItem('showDocs', String(showDocs));
|
||||
}
|
||||
|
||||
export default function* (): Generator {
|
||||
yield takeEvery(AppActionType.Startup, handleStartup);
|
||||
yield takeEvery(AppActionType.ToggleDocs, storeDocsState);
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
import { all, put } from 'redux-saga/effects';
|
||||
import { startup } from '../actions/app';
|
||||
import app from './app';
|
||||
import bleUart from './ble-uart';
|
||||
import editor from './editor';
|
||||
import errorLog from './error-log';
|
||||
@@ -18,7 +17,6 @@ import terminal from './terminal';
|
||||
/* istanbul ignore next */
|
||||
export default function* (): Generator {
|
||||
yield all([
|
||||
app(),
|
||||
bleUart(),
|
||||
lwp3BootloaderBle(),
|
||||
lwp3BootloaderProtocol(),
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright (c) 2020 The Pybricks Authors
|
||||
// Copyright (c) 2020-2021 The Pybricks Authors
|
||||
// File: sagas/app.test.ts
|
||||
// Tests for app sagas.
|
||||
|
||||
import { AsyncSaga } from '../../test';
|
||||
import { AppActionType, startup, toggleDocs } from '../actions/app';
|
||||
import app from './app';
|
||||
import { startup } from '../actions/app';
|
||||
import { SettingsActionType, toggleDarkMode, toggleDocs } from '../actions/settings';
|
||||
import settings from './settings';
|
||||
|
||||
afterAll(() => {
|
||||
jest.restoreAllMocks();
|
||||
@@ -13,7 +14,7 @@ afterAll(() => {
|
||||
|
||||
describe('startup', () => {
|
||||
test('with large screen', async () => {
|
||||
const saga = new AsyncSaga(app);
|
||||
const saga = new AsyncSaga(settings);
|
||||
|
||||
jest.spyOn(
|
||||
Object.getPrototypeOf(window.localStorage),
|
||||
@@ -25,13 +26,13 @@ describe('startup', () => {
|
||||
|
||||
// toggles documentation to be visible
|
||||
const toggleDocsAction = await saga.take();
|
||||
expect(toggleDocsAction.type).toBe(AppActionType.ToggleDocs);
|
||||
expect(toggleDocsAction.type).toBe(SettingsActionType.ToggleDocs);
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
|
||||
test('with small screen', async () => {
|
||||
const saga = new AsyncSaga(app);
|
||||
const saga = new AsyncSaga(settings);
|
||||
|
||||
jest.spyOn(
|
||||
Object.getPrototypeOf(window.localStorage),
|
||||
@@ -47,30 +48,30 @@ describe('startup', () => {
|
||||
});
|
||||
|
||||
test('with stored value "true"', async () => {
|
||||
const saga = new AsyncSaga(app);
|
||||
const saga = new AsyncSaga(settings);
|
||||
|
||||
jest.spyOn(
|
||||
Object.getPrototypeOf(window.localStorage),
|
||||
'getItem',
|
||||
).mockReturnValue('true');
|
||||
).mockReturnValue('{"showDocs":true}');
|
||||
innerWidth = 800;
|
||||
|
||||
saga.put(startup());
|
||||
|
||||
// toggles documentation to be visible
|
||||
const toggleDocsAction = await saga.take();
|
||||
expect(toggleDocsAction.type).toBe(AppActionType.ToggleDocs);
|
||||
expect(toggleDocsAction.type).toBe(SettingsActionType.ToggleDocs);
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
|
||||
test('with stored value "false"', async () => {
|
||||
const saga = new AsyncSaga(app);
|
||||
const saga = new AsyncSaga(settings);
|
||||
|
||||
jest.spyOn(
|
||||
Object.getPrototypeOf(window.localStorage),
|
||||
'getItem',
|
||||
).mockReturnValue('false');
|
||||
).mockReturnValue('{"showDocs":false}');
|
||||
innerWidth = 1024;
|
||||
|
||||
saga.put(startup());
|
||||
@@ -81,28 +82,36 @@ describe('startup', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('storeDocsState', () => {
|
||||
test('showing', async () => {
|
||||
const saga = new AsyncSaga(app);
|
||||
describe('store settings to local storage', () => {
|
||||
test('showDocs', async () => {
|
||||
const saga = new AsyncSaga(settings);
|
||||
|
||||
// NOTE: we aren't testing reducers here, so value doesn't change
|
||||
// even though we call the toggle function
|
||||
const mockSetItem = jest
|
||||
.spyOn(Object.getPrototypeOf(window.localStorage), 'setItem')
|
||||
.mockImplementation((_key, value) => expect(value).toBe('true'));
|
||||
saga.setState({ app: { showSettings: false, showDocs: true } });
|
||||
.mockImplementation((_key, value) =>
|
||||
expect(value).toBe('{"darkMode":false,"showDocs":true}'),
|
||||
);
|
||||
saga.setState({ settings: { darkMode: false, showDocs: true } });
|
||||
saga.put(toggleDocs());
|
||||
expect(mockSetItem).toHaveBeenCalled();
|
||||
|
||||
await saga.end();
|
||||
});
|
||||
|
||||
test('hidden', async () => {
|
||||
const saga = new AsyncSaga(app);
|
||||
test('darkMode', async () => {
|
||||
const saga = new AsyncSaga(settings);
|
||||
|
||||
// NOTE: we aren't testing reducers here, so value doesn't change
|
||||
// even though we call the toggle function
|
||||
const mockSetItem = jest
|
||||
.spyOn(Object.getPrototypeOf(window.localStorage), 'setItem')
|
||||
.mockImplementation((_key, value) => expect(value).toBe('false'));
|
||||
saga.setState({ app: { showSettings: false, showDocs: false } });
|
||||
saga.put(toggleDocs());
|
||||
.mockImplementation((_key, value) =>
|
||||
expect(value).toBe('{"darkMode":true,"showDocs":false}'),
|
||||
);
|
||||
saga.setState({ settings: { darkMode: true, showDocs: false } });
|
||||
saga.put(toggleDarkMode());
|
||||
expect(mockSetItem).toHaveBeenCalled();
|
||||
|
||||
await saga.end();
|
||||
+12
-5
@@ -1,17 +1,23 @@
|
||||
import { put, select, takeEvery } from 'redux-saga/effects';
|
||||
import { AppActionType } from '../actions/app';
|
||||
import { SettingsActionType, toggleDarkMode } from '../actions/settings';
|
||||
import { SettingsActionType, toggleDarkMode, toggleDocs } from '../actions/settings';
|
||||
import { RootState } from '../reducers';
|
||||
import { SettingsState } from '../reducers/settings';
|
||||
|
||||
function* loadSettings(): Generator {
|
||||
const settingsString = localStorage.getItem('settings');
|
||||
if (!settingsString) {
|
||||
return;
|
||||
}
|
||||
const settingsString = localStorage.getItem('settings') || '{}';
|
||||
const settings = JSON.parse(settingsString) as SettingsState;
|
||||
|
||||
// TODO: there has to be a better way to initialize app state from settings
|
||||
|
||||
if (
|
||||
settings.showDocs === undefined
|
||||
? window.innerWidth >= 1024
|
||||
: settings.showDocs === true
|
||||
) {
|
||||
yield put(toggleDocs());
|
||||
}
|
||||
|
||||
if (settings.darkMode) {
|
||||
yield put(toggleDarkMode());
|
||||
}
|
||||
@@ -22,6 +28,7 @@ function* saveSettings(): Generator {
|
||||
localStorage.setItem('settings', JSON.stringify(settings));
|
||||
}
|
||||
|
||||
// TODO: this should really be part of component, not saga
|
||||
function* updateDarkModeClass(): Generator {
|
||||
const darkMode = (yield select((s: RootState) => s.settings.darkMode)) as boolean;
|
||||
if (darkMode) {
|
||||
|
||||
Reference in New Issue
Block a user