Skip to content

Commit

Permalink
feat(query-devtools): Persist picture-in-picture mode through reloads (
Browse files Browse the repository at this point in the history
…#6942)

This feature allows the picture-in-picture mode of the devtools to persists through page reloads.

The popup will remain open and will be re-used between page refreshes.
  • Loading branch information
ardeora authored Feb 19, 2024
1 parent 63dcb08 commit d572279
Showing 1 changed file with 33 additions and 14 deletions.
47 changes: 33 additions & 14 deletions packages/query-devtools/src/Devtools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { Key } from '@solid-primitives/keyed'
import { createLocalStorage } from '@solid-primitives/storage'
import { createResizeObserver } from '@solid-primitives/resize-observer'
import { DropdownMenu, RadioGroup } from '@kobalte/core'
import { Portal, delegateEvents } from 'solid-js/web'
import { Portal, clearDelegatedEvents, delegateEvents } from 'solid-js/web'
import { tokens } from './theme'
import {
convertRemToPixels,
Expand Down Expand Up @@ -115,6 +115,8 @@ export type DevtoolsComponentType = Component<QueryDevtoolsProps>

interface PiPProviderProps {
children: JSX.Element
localStore: StorageObject<string>
setLocalStore: StorageSetter<string, unknown>
}

type PiPContextType = {
Expand Down Expand Up @@ -147,17 +149,31 @@ const PiPProvider = (props: PiPProviderProps) => {
return
}

const pip = window.open('', '', `width=${width},height=${height},popup`)
const pip = window.open(
'',
'TSQD-Devtools-Panel',
`width=${width},height=${height},popup`,
)

if (!pip) {
throw new Error(
'Failed to open popup. Please allow popups for this site to view the devtools in picture-in-picture mode.',
)
}

// Remove existing styles
pip.document.head.innerHTML = ''
// Remove existing body
pip.document.body.innerHTML = ''
// Clear Delegated Events
clearDelegatedEvents(pip.document)

pip.document.title = 'TanStack Query Devtools'
pip.document.body.style.margin = '0'

// Detect when window is closed by user
pip.addEventListener('pagehide', () => {
props.setLocalStore('pip_open', 'false')
setPipWindow(null)
})

Expand Down Expand Up @@ -208,20 +224,18 @@ const PiPProvider = (props: PiPProviderProps) => {
],
pip.document,
)
props.setLocalStore('pip_open', 'true')
setPipWindow(pip)
}

createEffect(() => {
// Close pipWindow when the main window is closed
const closePipWindowOnUnload = () => {
closePipWindow()
const pip_open = (props.localStore.pip_open ?? 'false') as 'true' | 'false'
if (pip_open === 'true') {
requestPipWindow(
Number(window.innerWidth),
Number(props.localStore.height || DEFAULT_HEIGHT),
)
}

window.addEventListener('beforeunload', closePipWindowOnUnload)

onCleanup(() => {
window.removeEventListener('beforeunload', closePipWindowOnUnload)
})
})

createEffect(() => {
Expand Down Expand Up @@ -286,7 +300,7 @@ const DevtoolsComponent: DevtoolsComponentType = (props) => {

return (
<QueryDevtoolsContext.Provider value={props}>
<PiPProvider>
<PiPProvider localStore={localStore} setLocalStore={setLocalStore}>
<ThemeContext.Provider value={theme}>
<Devtools localStore={localStore} setLocalStore={setLocalStore} />
</ThemeContext.Provider>
Expand Down Expand Up @@ -358,9 +372,13 @@ const Devtools: Component<DevtoolsPanelProps> = (props) => {
})
})

const pip_open = createMemo(
() => (props.localStore.pip_open ?? 'false') as 'true' | 'false',
)

return (
<>
<Show when={pip().pipWindow}>
<Show when={pip().pipWindow && pip_open() == 'true'}>
<Portal mount={pip().pipWindow?.document.body}>
<PiPPanel>
<ContentView
Expand Down Expand Up @@ -413,7 +431,7 @@ const Devtools: Component<DevtoolsPanelProps> = (props) => {
ref={transitionsContainerRef}
>
<TransitionGroup name="tsqd-panel-transition">
<Show when={isOpen() && !pip().pipWindow}>
<Show when={isOpen() && !pip().pipWindow && pip_open() == 'false'}>
<DevtoolsPanel
localStore={props.localStore}
setLocalStore={props.setLocalStore}
Expand Down Expand Up @@ -480,6 +498,7 @@ const PiPPanel: Component<{
}
if (win) {
win.addEventListener('resize', resizeCB)
resizeCB()
}

onCleanup(() => {
Expand Down

0 comments on commit d572279

Please sign in to comment.