From 89523b39155b13864ee5c93d06ab29a211f6a047 Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 30 Jan 2021 11:46:50 -0600 Subject: [PATCH] make license dialog state local --- src/about/AboutDialog.tsx | 20 ++++++++++++++------ src/app/actions.ts | 24 +----------------------- src/app/reducers.test.ts | 14 -------------- src/app/reducers.ts | 12 ------------ src/licenses/LicenseDialog.tsx | 26 +++++++++++++++----------- src/licenses/actions.ts | 8 ++++++++ src/licenses/sagas.test.ts | 9 ++++----- src/licenses/sagas.ts | 5 ++--- 8 files changed, 44 insertions(+), 74 deletions(-) diff --git a/src/about/AboutDialog.tsx b/src/about/AboutDialog.tsx index 56b1782f..2a3070df 100644 --- a/src/about/AboutDialog.tsx +++ b/src/about/AboutDialog.tsx @@ -7,7 +7,7 @@ import { AnchorButton, Button, Classes, Dialog } from '@blueprintjs/core'; import { WithI18nProps, withI18n } from '@shopify/react-i18n'; import React from 'react'; import { connect } from 'react-redux'; -import { closeAboutDialog, openLicenseDialog } from '../app/actions'; +import { closeAboutDialog } from '../app/actions'; import { appName, legoDisclaimer, @@ -26,13 +26,17 @@ const version = process.env.REACT_APP_VERSION; type StateProps = { showAboutDialog: boolean }; -type DispatchProps = { onClose: () => void; onLicenseButtonClick: () => void }; +type DispatchProps = { onClose: () => void }; type AboutDialogProps = StateProps & DispatchProps & WithI18nProps; class AboutDialog extends React.Component { + public state = { + licenseDialogIsOpen: false, + }; + render(): JSX.Element { - const { i18n, showAboutDialog, onClose, onLicenseButtonClick } = this.props; + const { i18n, showAboutDialog, onClose } = this.props; return ( { {legoDisclaimer}

- @@ -62,7 +68,10 @@ class AboutDialog extends React.Component {
- + this.setState({ licenseDialogIsOpen: false })} + />
); } @@ -74,7 +83,6 @@ const mapStateToProps = (state: RootState): StateProps => ({ const mapDispatchToProps: DispatchProps = { onClose: closeAboutDialog, - onLicenseButtonClick: openLicenseDialog, }; export default connect( diff --git a/src/app/actions.ts b/src/app/actions.ts index bfbc2936..7ef88ee9 100644 --- a/src/app/actions.ts +++ b/src/app/actions.ts @@ -32,10 +32,6 @@ export enum AppActionType { OpenAboutDialog = 'app.action.openAboutDialog', /** Close about dialog. */ CloseAboutDialog = 'app.action.closeAboutDialog', - /** Open license dialog. */ - OpenLicenseDialog = 'app.action.openLicenseDialog', - /** Close license dialog. */ - CloseLicenseDialog = 'app.action.closeLicenseDialog', } /** Action that requests the app to reload. */ @@ -148,22 +144,6 @@ export function closeAboutDialog(): AppCloseAboutDialogAction { return { type: AppActionType.CloseAboutDialog }; } -/** Action to open the license dialog. */ -export type AppOpenLicenseDialogAction = Action; - -/** Creates an action to open the license dialog. */ -export function openLicenseDialog(): AppOpenLicenseDialogAction { - return { type: AppActionType.OpenLicenseDialog }; -} - -/** Action to close the license dialog. */ -export type AppCloseLicenseDialogAction = Action; - -/** Creates an action to close the license dialog. */ -export function closeLicenseDialog(): AppCloseLicenseDialogAction { - return { type: AppActionType.CloseLicenseDialog }; -} - /** common type for all app actions. */ export type AppAction = | AppReloadAction @@ -177,6 +157,4 @@ export type AppAction = | AppOpenSettingsAction | AppCloseSettingsAction | AppOpenAboutDialogAction - | AppCloseAboutDialogAction - | AppOpenLicenseDialogAction - | AppCloseLicenseDialogAction; + | AppCloseAboutDialogAction; diff --git a/src/app/reducers.test.ts b/src/app/reducers.test.ts index 274821e2..8f4c8bb1 100644 --- a/src/app/reducers.test.ts +++ b/src/app/reducers.test.ts @@ -7,7 +7,6 @@ import { BeforeInstallPromptEvent } from '../utils/dom'; import { checkForUpdate, closeAboutDialog, - closeLicenseDialog, closeSettings, didBeforeInstallPrompt, didCheckForUpdate, @@ -15,7 +14,6 @@ import { didInstallPrompt, installPrompt, openAboutDialog, - openLicenseDialog, openSettings, } from './actions'; import reducers from './reducers'; @@ -31,7 +29,6 @@ test('initial state', () => { "readyForOfflineUse": false, "serviceWorker": null, "showAboutDialog": false, - "showLicenseDialog": false, "showSettings": false, "updateAvailable": false, } @@ -58,17 +55,6 @@ test('showAboutDialog', () => { ).toBe(false); }); -test('showLicenseDialog', () => { - expect( - reducers({ showLicenseDialog: false } as State, openLicenseDialog()) - .showLicenseDialog, - ).toBe(true); - expect( - reducers({ showLicenseDialog: true } as State, closeLicenseDialog()) - .showLicenseDialog, - ).toBe(false); -}); - test('serviceWorker', () => { const registration = {} as ServiceWorkerRegistration; expect( diff --git a/src/app/reducers.ts b/src/app/reducers.ts index ac0c09eb..cbb8cc3d 100644 --- a/src/app/reducers.ts +++ b/src/app/reducers.ts @@ -31,17 +31,6 @@ const showAboutDialog: Reducer = (state = false, action) => { } }; -const showLicenseDialog: Reducer = (state = false, action) => { - switch (action.type) { - case AppActionType.OpenLicenseDialog: - return true; - case AppActionType.CloseLicenseDialog: - return false; - default: - return state; - } -}; - const serviceWorker: Reducer = ( state = null, action, @@ -117,7 +106,6 @@ const readyForOfflineUse: Reducer = (state = false, action) => export default combineReducers({ showSettings, showAboutDialog, - showLicenseDialog, serviceWorker, checkingForUpdate, updateAvailable, diff --git a/src/licenses/LicenseDialog.tsx b/src/licenses/LicenseDialog.tsx index cf442a79..1838aa71 100644 --- a/src/licenses/LicenseDialog.tsx +++ b/src/licenses/LicenseDialog.tsx @@ -15,10 +15,9 @@ import { import { WithI18nProps, withI18n } from '@shopify/react-i18n'; import React from 'react'; import { connect } from 'react-redux'; -import { closeLicenseDialog } from '../app/actions'; import { appName } from '../app/constants'; import { RootState } from '../reducers'; -import { select } from './actions'; +import { fetchList, select } from './actions'; import { LicenseStringId } from './i18n'; import en from './i18n.en.json'; import { LicenseInfo, LicenseList } from './reducers'; @@ -26,34 +25,40 @@ import { LicenseInfo, LicenseList } from './reducers'; import './license.scss'; type StateProps = { - showLicenseDialog: boolean; licenseList: LicenseList | null; licenseInfo: LicenseInfo | null; }; type DispatchProps = { - onClose: () => void; + onOpening: () => void; onSelectPackage: (info: LicenseInfo) => void; }; -type LicenseDialogProps = StateProps & DispatchProps & WithI18nProps; +type OwnProps = { + isOpen: boolean; + onClose(): void; +}; + +type LicenseDialogProps = StateProps & DispatchProps & OwnProps & WithI18nProps; class LicenseDialog extends React.Component { render(): JSX.Element { const infoDiv = React.createRef(); const { - i18n, - showLicenseDialog, - onClose, licenseList, licenseInfo, + onOpening, onSelectPackage, + isOpen, + onClose, + i18n, } = this.props; return ( onOpening()} onClose={() => onClose()} className="pb-license-dialog" > @@ -146,13 +151,12 @@ class LicenseDialog extends React.Component { } const mapStateToProps = (state: RootState): StateProps => ({ - showLicenseDialog: state.app.showLicenseDialog, licenseList: state.licenses.list, licenseInfo: state.licenses.selected, }); const mapDispatchToProps: DispatchProps = { - onClose: closeLicenseDialog, + onOpening: fetchList, onSelectPackage: select, }; diff --git a/src/licenses/actions.ts b/src/licenses/actions.ts index 8732ef0e..748188fa 100644 --- a/src/licenses/actions.ts +++ b/src/licenses/actions.ts @@ -5,11 +5,18 @@ import { Action } from 'redux'; import { LicenseInfo, LicenseList } from './reducers'; export enum LicenseActionType { + FetchList = 'license.action.fetchList', DidFetchList = 'license.action.didFetchList', DidFailToFetchList = 'license.action.didFailToFetchList', Select = 'license.action.select', } +export type LicenseFetchListAction = Action; + +export function fetchList(): LicenseFetchListAction { + return { type: LicenseActionType.FetchList }; +} + export type LicenseDidFetchListAction = Action & { list: LicenseList; }; @@ -35,6 +42,7 @@ export function select(info: LicenseInfo): LicenseSelectAction { } export type LicenseAction = + | LicenseFetchListAction | LicenseDidFetchListAction | LicenseDidFailToFetchListAction | LicenseSelectAction; diff --git a/src/licenses/sagas.test.ts b/src/licenses/sagas.test.ts index 891f9efe..7defd253 100644 --- a/src/licenses/sagas.test.ts +++ b/src/licenses/sagas.test.ts @@ -4,8 +4,7 @@ // Tests for license sagas. import { AsyncSaga, delay } from '../../test'; -import { openLicenseDialog } from '../app/actions'; -import { didFailToFetchList, didFetchList } from './actions'; +import { didFailToFetchList, didFetchList, fetchList } from './actions'; import { LicenseList } from './reducers'; import license from './sagas'; @@ -24,7 +23,7 @@ describe('fetchLicenses', () => { // initially, license list starts as null, so fetch is called to get // the list - saga.put(openLicenseDialog()); + saga.put(fetchList()); const action = await saga.take(); expect(action).toEqual(didFetchList(testLicenseList)); @@ -41,7 +40,7 @@ describe('fetchLicenses', () => { // after we have the list, we don't fetch it again since it will // always be the same list - saga.put(openLicenseDialog()); + saga.put(fetchList()); // have to yield to be sure fetch call would have taken place on error await delay(0); @@ -54,7 +53,7 @@ describe('fetchLicenses', () => { jest.spyOn(globalThis, 'fetch').mockResolvedValue(failResponse); - saga.put(openLicenseDialog()); + saga.put(fetchList()); const action = await saga.take(); expect(action).toEqual(didFailToFetchList(failResponse)); diff --git a/src/licenses/sagas.ts b/src/licenses/sagas.ts index 35854885..aaef64aa 100644 --- a/src/licenses/sagas.ts +++ b/src/licenses/sagas.ts @@ -2,9 +2,8 @@ // Copyright (c) 2021 The Pybricks Authors import { call, put, select, takeEvery } from 'typed-redux-saga/macro'; -import { AppActionType } from '../app/actions'; import { RootState } from '../reducers'; -import { didFailToFetchList, didFetchList } from './actions'; +import { LicenseActionType, didFailToFetchList, didFetchList } from './actions'; function* fetchLicenses(): Generator { const licenses = yield* select((s: RootState) => s.licenses.list); @@ -25,5 +24,5 @@ function* fetchLicenses(): Generator { } export default function* (): Generator { - yield* takeEvery(AppActionType.OpenLicenseDialog, fetchLicenses); + yield* takeEvery(LicenseActionType.FetchList, fetchLicenses); }