mirror of
https://github.com/supabase/supabase.git
synced 2026-07-05 09:05:10 +08:00
70 lines
2.1 KiB
TypeScript
70 lines
2.1 KiB
TypeScript
'use client'
|
|
|
|
import { isEqual } from 'lodash'
|
|
import { useEffect, useMemo, useRef } from 'react'
|
|
import { useSnapshot } from 'valtio'
|
|
|
|
import type { ICommand, CommandOptions } from '../types'
|
|
import { useCommandContext } from '../../internal/Context'
|
|
import { useCurrentPage } from './pagesHooks'
|
|
import { PageDefinition, isCommandsPage } from '../../internal/state/pagesState'
|
|
|
|
const useCommands = () => {
|
|
const { commandsState } = useCommandContext()
|
|
const { commandSections } = useSnapshot(commandsState)
|
|
|
|
const _currPage = useCurrentPage()
|
|
const currPage = _currPage as PageDefinition
|
|
if (currPage && isCommandsPage(currPage)) return currPage.sections
|
|
|
|
return commandSections
|
|
}
|
|
|
|
const useRegisterCommands = (
|
|
sectionName: string,
|
|
commands: ICommand[],
|
|
options: CommandOptions = {}
|
|
) => {
|
|
const { commandsState } = useCommandContext()
|
|
const { registerSection } = useSnapshot(commandsState)
|
|
|
|
const prevDeps = useRef(options?.deps)
|
|
options.enabled ??= true
|
|
const prevEnabled = useRef<boolean | undefined>(options.enabled)
|
|
|
|
const unsubscribe = useRef<() => void>()
|
|
|
|
/**
|
|
* useEffect handles the registration on first render, since React runs the
|
|
* first render twice in development. (Otherwise the first render would leave
|
|
* a dangling subscription.)
|
|
*
|
|
* It also handles final cleanup, since useMemo can't do this.
|
|
*
|
|
* useMemo handles the registration on subsequent renders, to ensure it
|
|
* happens synchronously.
|
|
*/
|
|
useMemo(() => {
|
|
if (!isEqual(prevDeps.current, options.deps) || prevEnabled.current !== options.enabled) {
|
|
unsubscribe.current?.()
|
|
|
|
unsubscribe.current = options.enabled
|
|
? registerSection(sectionName, commands, options)
|
|
: undefined
|
|
|
|
prevDeps.current = options.deps
|
|
prevEnabled.current = options.enabled
|
|
}
|
|
}, [registerSection, sectionName, commands, options])
|
|
|
|
useEffect(() => {
|
|
unsubscribe.current = options.enabled
|
|
? registerSection(sectionName, commands, options)
|
|
: undefined
|
|
|
|
return () => unsubscribe.current?.()
|
|
}, [])
|
|
}
|
|
|
|
export { useCommands, useRegisterCommands }
|