2021-10-04 17:41:45 +00:00
|
|
|
import * as React from "react"
|
2021-10-06 00:52:06 +00:00
|
|
|
import {ContextData} from "../types/ContextTypes"
|
|
|
|
import {WithChildren} from "../types/ExtraTypes"
|
|
|
|
import {SophonInstanceDetails} from "../types/SophonTypes"
|
2021-10-04 17:41:45 +00:00
|
|
|
|
|
|
|
// States
|
|
|
|
|
|
|
|
type InstanceNotSelected = {
|
|
|
|
url: undefined,
|
|
|
|
details: undefined,
|
|
|
|
}
|
|
|
|
|
|
|
|
type InstanceSelected = {
|
|
|
|
url: URL,
|
|
|
|
details: SophonInstanceDetails,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Actions
|
|
|
|
|
|
|
|
type InstanceSelect = {
|
|
|
|
type: "select",
|
|
|
|
url: URL,
|
|
|
|
details: SophonInstanceDetails,
|
|
|
|
}
|
|
|
|
|
|
|
|
type InstanceDeselect = {
|
|
|
|
type: "deselect",
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Composition
|
|
|
|
|
2021-10-06 15:17:16 +00:00
|
|
|
export type InstanceState = InstanceSelected | InstanceNotSelected
|
2021-10-04 17:41:45 +00:00
|
|
|
type InstanceAction = InstanceSelect | InstanceDeselect
|
2021-10-06 00:52:06 +00:00
|
|
|
export type InstanceContextData = ContextData<InstanceState, InstanceAction> | undefined
|
2021-10-04 17:41:45 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Definitions
|
|
|
|
|
|
|
|
const instanceDefaultState: InstanceState = {
|
|
|
|
url: undefined,
|
|
|
|
details: undefined,
|
|
|
|
}
|
|
|
|
|
|
|
|
const instanceReducer: React.Reducer<InstanceState, InstanceAction> = (prevState, action) => {
|
|
|
|
switch (action.type) {
|
|
|
|
case "select":
|
2021-10-06 00:52:06 +00:00
|
|
|
// Bail out if trying to select the current instance
|
|
|
|
if(action.url === prevState.url) {
|
|
|
|
return prevState
|
|
|
|
}
|
|
|
|
|
2021-10-04 17:41:45 +00:00
|
|
|
return {
|
|
|
|
url: action.url,
|
|
|
|
details: action.details,
|
|
|
|
}
|
|
|
|
case "deselect":
|
2021-10-06 00:52:06 +00:00
|
|
|
// Bail out if no instance is currently selected
|
|
|
|
if(prevState.url === undefined) {
|
|
|
|
return prevState
|
2021-10-04 17:41:45 +00:00
|
|
|
}
|
2021-10-06 00:52:06 +00:00
|
|
|
|
|
|
|
return instanceDefaultState
|
2021-10-04 17:41:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const instanceContext = React.createContext<InstanceContextData>(undefined)
|
|
|
|
const InstanceContext = instanceContext
|
|
|
|
|
|
|
|
|
|
|
|
// Hooks
|
|
|
|
|
|
|
|
export function useInstanceReducer(): InstanceContextData {
|
|
|
|
const [state, dispatch] = React.useReducer(instanceReducer, instanceDefaultState)
|
|
|
|
return {state, dispatch}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function useInstanceContext(): InstanceContextData {
|
|
|
|
return React.useContext(instanceContext)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Components
|
|
|
|
|
|
|
|
export function InstanceProvider({children}: WithChildren): JSX.Element {
|
|
|
|
const reducer = useInstanceReducer()
|
|
|
|
|
|
|
|
return <InstanceContext.Provider value={reducer} children={children}/>
|
|
|
|
}
|