Skip to content

Commit

Permalink
Switch to query param for yarn plugin setting (#16)
Browse files Browse the repository at this point in the history
* updateURL improvements

- Make parameters independent from one another by
  using the URL constructor rather than string
  concatenation to build up the URL.
- Switch from `replaceState` to `pushState` so
  users can navigate between different
  configurations using the browser forward and
  back buttons
- Trigger a `popstate` event after updating the
  URL. This allows hooks like `useSearchParams` to
  pick up the change

* Move yarnPlugin setting to URL

This allows us to send people to the right version
of the diff depending on whether they have the
yarn plugin installed from places like the
versions:bump command.

* Make settings checkboxes controlled

Guarantees that checkboxes are in sync with the
underlying settings
  • Loading branch information
mtlewis authored Oct 18, 2024
1 parent 8380e76 commit c908ca7
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 30 deletions.
38 changes: 33 additions & 5 deletions src/SettingsProvider.jsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,51 @@
import React, { useContext } from 'react'
import React, { useCallback, useContext } from 'react'
import useLocalStorage from 'react-use/lib/useLocalStorage'
import useSearchParam from 'react-use/lib/useSearchParam'

import { SHOW_LATEST_RCS, USE_YARN_PLUGIN } from './utils'
import { updateURL } from './utils/update-url'

const INITIAL_STATE = {
[`${SHOW_LATEST_RCS}`]: false,
[`${USE_YARN_PLUGIN}`]: false
[`${SHOW_LATEST_RCS}`]: false
}

export const SettingsContext = React.createContext(INITIAL_STATE)

export const SettingsProvider = React.memo(function({ children }) {
const [settings, setSettings] = useLocalStorage(
const useYarnPlugin = useSearchParam('yarnPlugin')

const [settings, setLocalStorageSettings] = useLocalStorage(
'backstage:upgrade-helper:settings',
INITIAL_STATE
)

const setUseYarnPlugin = useYarnPlugin => {
updateURL({ yarnPlugin: useYarnPlugin })
}

const setSettings = useCallback(settings => {
const {
[USE_YARN_PLUGIN]: newUseYarnPlugin,
...localStorageSettings
} = settings

if (newUseYarnPlugin !== useYarnPlugin) {
setUseYarnPlugin(newUseYarnPlugin)
}

setLocalStorageSettings(localStorageSettings)
})

return (
<SettingsContext.Provider value={{ settings, setSettings }}>
<SettingsContext.Provider
value={{
settings: {
...settings,
[USE_YARN_PLUGIN]: !!JSON.parse(useYarnPlugin)
},
setSettings
}}
>
{children}
</SettingsContext.Provider>
)
Expand Down
13 changes: 7 additions & 6 deletions src/components/common/Settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ const Settings = () => {
setVisibility(visibility)
}

const toggleShowLatestRCs = () =>
const toggleShowLatestRCs = e =>
setSettings({
...settings,
[SHOW_LATEST_RCS]: !settings[SHOW_LATEST_RCS]
[SHOW_LATEST_RCS]: e.target.checked
})

const toggleUseYarnPlugin = () =>
const toggleUseYarnPlugin = e => {
setSettings({
...settings,
[USE_YARN_PLUGIN]: !settings[USE_YARN_PLUGIN]
[USE_YARN_PLUGIN]: e.target.checked
})
}

return (
<Popover
Expand All @@ -38,15 +39,15 @@ const Settings = () => {
<>
<div>
<Checkbox
defaultChecked={settings[SHOW_LATEST_RCS]}
checked={settings[SHOW_LATEST_RCS]}
onChange={toggleShowLatestRCs}
>
{SHOW_LATEST_RCS}
</Checkbox>
</div>
<div>
<Checkbox
defaultChecked={settings[USE_YARN_PLUGIN]}
checked={settings[USE_YARN_PLUGIN]}
onChange={toggleUseYarnPlugin}
>
{USE_YARN_PLUGIN}
Expand Down
52 changes: 33 additions & 19 deletions src/utils/update-url.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,37 @@ export function updateURL({
language,
isPackageNameDefinedInURL,
fromVersion,
toVersion
}) {
const pageURL = window.location.href.replace(window.location.search, '')

const newURL =
fromVersion !== '' || toVersion !== ''
? `?from=${fromVersion}&to=${toVersion}`
: '?'
const packageNameInURL = isPackageNameDefinedInURL
? `&package=${packageName}`
: ''
const languageInURL =
packageName === PACKAGE_NAMES.RNW ? `&language=${language}` : ''

window.history.replaceState(
null,
null,
`${pageURL}${newURL}${packageNameInURL}${languageInURL}`
)
toVersion,
yarnPlugin
} = {}) {
const newURL = new URL(window.location.href)

if (fromVersion) {
newURL.searchParams.set('fromVersion', fromVersion)
}

if (toVersion) {
newURL.searchParams.set('toVersion', toVersion)
}

if (yarnPlugin !== undefined) {
newURL.searchParams.set('yarnPlugin', yarnPlugin ? '1' : '0')
}

if (isPackageNameDefinedInURL) {
newURL.searchParams.set('package', packageName)
}

if (language && packageName === PACKAGE_NAMES.RNW) {
newURL.searchParams.set('language', language)
}

window.history.pushState('', '', newURL.toString())

// The popstate event is not triggered by window.history.pushState,
// so we need to dispatch the event ourselves in order for listeners
// to pick it up.
//
// https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event#the_history_stacks
dispatchEvent(new PopStateEvent('popstate'))
}

0 comments on commit c908ca7

Please sign in to comment.