@@ -7,7 +7,14 @@ import {
77 visit ,
88} from 'graphql' ;
99import { VariableToType } from 'graphql-language-service' ;
10- import { ReactNode , useCallback , useMemo , useState } from 'react' ;
10+ import {
11+ ReactNode ,
12+ useCallback ,
13+ useEffect ,
14+ useMemo ,
15+ useRef ,
16+ useState ,
17+ } from 'react' ;
1118
1219import { useStorageContext } from '../storage' ;
1320import { createContextHook , createNullableContext } from '../utility/context' ;
@@ -24,6 +31,9 @@ import {
2431 useSetEditorValues ,
2532 useStoreTabs ,
2633 useSynchronizeActiveTabValues ,
34+ clearHeadersFromTabs ,
35+ serializeTabState ,
36+ STORAGE_KEY as STORAGE_KEY_TABS ,
2737} from './tabs' ;
2838import { CodeMirrorEditor } from './types' ;
2939import { STORAGE_KEY as STORAGE_KEY_VARIABLES } from './variable-editor' ;
@@ -139,6 +149,10 @@ export type EditorContextType = TabsState & {
139149 * If the contents of the headers editor are persisted in storage.
140150 */
141151 shouldPersistHeaders : boolean ;
152+ /**
153+ * Changes if headers should be persisted.
154+ */
155+ setShouldPersistHeaders ( persist : boolean ) : void ;
142156} ;
143157
144158export const EditorContext =
@@ -260,14 +274,23 @@ export function EditorContextProvider(props: EditorContextProviderProps) {
260274 null ,
261275 ) ;
262276
277+ const [ shouldPersistHeaders , setShouldPersistHeadersInternal ] = useState (
278+ ( ) => {
279+ const isStored = storage ?. get ( PERSIST_HEADERS_STORAGE_KEY ) !== null ;
280+ return props . shouldPersistHeaders !== false && isStored
281+ ? storage ?. get ( PERSIST_HEADERS_STORAGE_KEY ) === 'true'
282+ : Boolean ( props . shouldPersistHeaders ) ;
283+ } ,
284+ ) ;
285+
263286 useSynchronizeValue ( headerEditor , props . headers ) ;
264287 useSynchronizeValue ( queryEditor , props . query ) ;
265288 useSynchronizeValue ( responseEditor , props . response ) ;
266289 useSynchronizeValue ( variableEditor , props . variables ) ;
267290
268291 const storeTabs = useStoreTabs ( {
269292 storage,
270- shouldPersistHeaders : props . shouldPersistHeaders ,
293+ shouldPersistHeaders,
271294 } ) ;
272295
273296 // We store this in state but never update it. By passing a function we only
@@ -304,6 +327,31 @@ export function EditorContextProvider(props: EditorContextProviderProps) {
304327
305328 const [ tabState , setTabState ] = useState < TabsState > ( initialState . tabState ) ;
306329
330+ const setShouldPersistHeaders = useCallback (
331+ ( persist : boolean ) => {
332+ if ( persist ) {
333+ storage ?. set ( STORAGE_KEY_HEADERS , headerEditor ?. getValue ( ) ?? '' ) ;
334+ const serializedTabs = serializeTabState ( tabState , true ) ;
335+ storage ?. set ( STORAGE_KEY_TABS , serializedTabs ) ;
336+ } else {
337+ storage ?. set ( STORAGE_KEY_HEADERS , '' ) ;
338+ clearHeadersFromTabs ( storage ) ;
339+ }
340+ setShouldPersistHeadersInternal ( persist ) ;
341+ storage ?. set ( PERSIST_HEADERS_STORAGE_KEY , persist . toString ( ) ) ;
342+ } ,
343+ [ storage , tabState , headerEditor ] ,
344+ ) ;
345+
346+ const lastShouldPersistHeadersProp = useRef < boolean | undefined > ( undefined ) ;
347+ useEffect ( ( ) => {
348+ const propValue = Boolean ( props . shouldPersistHeaders ) ;
349+ if ( lastShouldPersistHeadersProp . current !== propValue ) {
350+ setShouldPersistHeaders ( propValue ) ;
351+ lastShouldPersistHeadersProp . current = propValue ;
352+ }
353+ } , [ props . shouldPersistHeaders , setShouldPersistHeaders ] ) ;
354+
307355 const synchronizeActiveTabValues = useSynchronizeActiveTabValues ( {
308356 queryEditor,
309357 variableEditor,
@@ -454,7 +502,8 @@ export function EditorContextProvider(props: EditorContextProviderProps) {
454502 externalFragments,
455503 validationRules,
456504
457- shouldPersistHeaders : props . shouldPersistHeaders || false ,
505+ shouldPersistHeaders,
506+ setShouldPersistHeaders,
458507 } ) ,
459508 [
460509 tabState ,
@@ -475,7 +524,8 @@ export function EditorContextProvider(props: EditorContextProviderProps) {
475524 externalFragments ,
476525 validationRules ,
477526
478- props . shouldPersistHeaders ,
527+ shouldPersistHeaders ,
528+ setShouldPersistHeaders ,
479529 ] ,
480530 ) ;
481531
@@ -488,6 +538,8 @@ export function EditorContextProvider(props: EditorContextProviderProps) {
488538
489539export const useEditorContext = createContextHook ( EditorContext ) ;
490540
541+ const PERSIST_HEADERS_STORAGE_KEY = 'shouldPersistHeaders' ;
542+
491543const DEFAULT_QUERY = `# Welcome to GraphiQL
492544#
493545# GraphiQL is an in-browser tool for writing, validating, and
0 commit comments