-
-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathRDTContext.tsx
127 lines (112 loc) · 3.82 KB
/
RDTContext.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import type { Dispatch } from "react"
import type React from "react"
import { createContext, useEffect, useMemo, useReducer } from "react"
import { useRemoveBody } from "../hooks/detached/useRemoveBody.js"
import { checkIsDetached, checkIsDetachedOwner, checkIsDetachedWindow } from "../utils/detached.js"
import { tryParseJson } from "../utils/sanitize.js"
import {
REMIX_DEV_TOOLS_CHECK_DETACHED,
REMIX_DEV_TOOLS_DETACHED,
REMIX_DEV_TOOLS_SETTINGS,
REMIX_DEV_TOOLS_STATE,
getStorageItem,
setSessionItem,
setStorageItem,
} from "../utils/storage.js"
import { type RemixDevToolsActions, type RemixDevToolsState, initialState, rdtReducer } from "./rdtReducer.js"
export const RDTContext = createContext<{
state: RemixDevToolsState
dispatch: Dispatch<RemixDevToolsActions>
}>({ state: initialState, dispatch: () => null })
RDTContext.displayName = "RDTContext"
interface ContextProps {
children: React.ReactNode
config?: RdtClientConfig
}
export const setIsDetachedIfRequired = () => {
const isDetachedWindow = checkIsDetachedWindow()
if (!isDetachedWindow && window.RDT_MOUNTED) {
setSessionItem(REMIX_DEV_TOOLS_DETACHED, "true")
}
}
export const resetIsDetachedCheck = () => {
setStorageItem(REMIX_DEV_TOOLS_CHECK_DETACHED, "false")
}
export const detachedModeSetup = () => {
resetIsDetachedCheck()
setIsDetachedIfRequired()
const isDetachedWindow = checkIsDetachedWindow()
const isDetached = checkIsDetached()
const isDetachedOwner = checkIsDetachedOwner()
if (isDetachedWindow && !isDetached) {
window.close()
}
if (!isDetached && isDetachedOwner) {
//setSessionItem(REMIX_DEV_TOOLS_DETACHED_OWNER, "false");
// isDetachedOwner = false;
}
return {
detachedWindow: window.RDT_MOUNTED ?? isDetachedWindow,
detachedWindowOwner: isDetachedOwner,
}
}
export const getSettings = () => {
const settingsString = getStorageItem(REMIX_DEV_TOOLS_SETTINGS)
const settings = tryParseJson<RemixDevToolsState["settings"]>(settingsString)
return {
...settings,
}
}
export const getExistingStateFromStorage = (config?: RdtClientConfig & { editorName?: string }) => {
const existingState = getStorageItem(REMIX_DEV_TOOLS_STATE)
const settings = getSettings()
const { detachedWindow, detachedWindowOwner } = detachedModeSetup()
const state: RemixDevToolsState = {
...initialState,
...(existingState ? JSON.parse(existingState) : {}),
settings: {
...initialState.settings,
...config,
...settings,
editorName: config?.editorName ?? initialState.settings.editorName,
liveUrls: config?.liveUrls ?? initialState.settings.liveUrls,
breakpoints: config?.breakpoints ?? initialState.settings.breakpoints,
},
detachedWindow,
detachedWindowOwner,
}
return state
}
export type RdtClientConfig = Pick<
RemixDevToolsState["settings"],
| "defaultOpen"
| "breakpoints"
| "showBreakpointIndicator"
| "showRouteBoundariesOn"
| "expansionLevel"
| "liveUrls"
| "position"
| "height"
| "minHeight"
| "maxHeight"
| "hideUntilHover"
| "panelLocation"
| "requireUrlFlag"
| "urlFlag"
| "routeBoundaryGradient"
>
export const RDTContextProvider = ({ children, config }: ContextProps) => {
const [state, dispatch] = useReducer<typeof rdtReducer>(rdtReducer, getExistingStateFromStorage(config))
// biome-ignore lint/correctness/useExhaustiveDependencies: investigate
const value = useMemo(() => ({ state, dispatch }), [state, dispatch])
useRemoveBody(state)
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { settings, detachedWindow, detachedWindowOwner, ...rest } = state
// Store user settings for dev tools into local storage
setStorageItem(REMIX_DEV_TOOLS_SETTINGS, JSON.stringify(settings))
// Store general state into local storage
setStorageItem(REMIX_DEV_TOOLS_STATE, JSON.stringify(rest))
}, [state])
return <RDTContext.Provider value={value}>{children}</RDTContext.Provider>
}