-
Notifications
You must be signed in to change notification settings - Fork 967
Expand file tree
/
Copy pathuseCustomCommands.ts
More file actions
104 lines (91 loc) · 2.89 KB
/
useCustomCommands.ts
File metadata and controls
104 lines (91 loc) · 2.89 KB
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
import { useReducer, useContext, useEffect } from "react"
import { produce } from "immer"
import type { Command } from "reactotron-core-contract"
import { CommandType } from "reactotron-core-contract"
import ReactotronContext from "../Reactotron"
export type CustomCommandArg = {
name: string
placeholder?: string
hidden?: boolean
}
export interface CustomCommand {
clientId: string
id: string
title?: string
command: string
description?: string
args?: CustomCommandArg[]
}
interface CustomCommandState {
customCommands: CustomCommand[]
}
enum CustomCommandsActionType {
CommandAdd = "COMMAND_ADD",
CommandRemove = "COMMAND_REMOVE",
CommandClear = "COMMAND_CLEAR",
}
type Action =
| {
type: CustomCommandsActionType.CommandAdd
payload: Command
}
| { type: CustomCommandsActionType.CommandRemove; payload: Command }
| { type: CustomCommandsActionType.CommandClear; payload: string }
function customCommandsReducer(state: CustomCommandState, action: Action) {
switch (action.type) {
case CustomCommandsActionType.CommandAdd:
return produce(state, (draftState) => {
draftState.customCommands.push({
clientId: action.payload.clientId,
...action.payload.payload,
})
})
case CustomCommandsActionType.CommandRemove:
return produce(state, (draftState) => {
const commandIndex = draftState.customCommands.findIndex(
(cc) => cc.clientId === action.payload.clientId && cc.id === action.payload.payload.id
)
if (commandIndex === -1) return
draftState.customCommands = [
...draftState.customCommands.slice(0, commandIndex),
...draftState.customCommands.slice(commandIndex + 1),
]
})
case CustomCommandsActionType.CommandClear:
return produce(state, (draftState) => {
draftState.customCommands = draftState.customCommands.filter(
(cc) => cc.clientId !== action.payload
)
})
default:
return state
}
}
function useCustomCommands() {
const { addCommandListener } = useContext(ReactotronContext)
const [state, dispatch] = useReducer(customCommandsReducer, { customCommands: [] })
useEffect(() => {
addCommandListener((command) => {
if (command.type === CommandType.ClientIntro) {
dispatch({
type: CustomCommandsActionType.CommandClear,
payload: command.clientId,
})
} else if (command.type === CommandType.CustomCommandRegister) {
dispatch({
type: CustomCommandsActionType.CommandAdd,
payload: command,
})
} else if (command.type === CommandType.CustomCommandUnregister) {
dispatch({
type: CustomCommandsActionType.CommandRemove,
payload: command,
})
}
})
}, [addCommandListener])
return {
customCommands: state.customCommands,
}
}
export default useCustomCommands