-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathkbs_context.ts
More file actions
79 lines (70 loc) · 2.25 KB
/
kbs_context.ts
File metadata and controls
79 lines (70 loc) · 2.25 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
import type { Dispatch } from 'react';
import { createContext, useContext } from 'react';
import type { KbsDefinition, KbsInternalShortcut } from './types.ts';
import { cleanShortcuts } from './utils/clean_shortcuts.ts';
import { combineShortcuts } from './utils/combine_shortcuts.ts';
interface KbsState {
inputShortcuts: ReadonlyArray<readonly KbsDefinition[]>;
cleanedShortcuts: readonly KbsInternalShortcut[];
combinedShortcuts: Record<string, KbsInternalShortcut>;
disableCount: number;
}
type KbsAction =
| { type: 'INIT'; shortcuts: readonly KbsDefinition[] }
| { type: 'CLEANUP'; shortcuts: readonly KbsDefinition[] }
| { type: 'DISABLE_GLOBAL' }
| { type: 'ENABLE_GLOBAL' };
export const initialKbsState: KbsState = {
inputShortcuts: [],
cleanedShortcuts: [],
combinedShortcuts: {},
disableCount: 0,
};
export const kbsContext = createContext<KbsState>(initialKbsState);
export const kbsDispatchContext = createContext<Dispatch<KbsAction> | null>(
null,
);
export function useKbsUncheckedDispatch() {
return useContext(kbsDispatchContext);
}
export function useKbsDispatch() {
const dispatch = useContext(kbsDispatchContext);
if (!dispatch) {
throw new Error('missing context');
}
return dispatch;
}
export function kbsReducer(state: KbsState, action: KbsAction): KbsState {
switch (action.type) {
case 'INIT': {
const newInputs = [...state.inputShortcuts, action.shortcuts];
const cleanedShortcuts = cleanShortcuts(newInputs);
return {
...state,
inputShortcuts: newInputs,
cleanedShortcuts,
combinedShortcuts: combineShortcuts(cleanedShortcuts),
};
}
case 'CLEANUP': {
const newInputs = state.inputShortcuts.filter(
(shortcuts) => shortcuts !== action.shortcuts,
);
const cleanedShortcuts = cleanShortcuts(newInputs);
return {
...state,
inputShortcuts: newInputs,
cleanedShortcuts,
combinedShortcuts: combineShortcuts(cleanedShortcuts),
};
}
case 'DISABLE_GLOBAL': {
return { ...state, disableCount: state.disableCount + 1 };
}
case 'ENABLE_GLOBAL': {
return { ...state, disableCount: state.disableCount - 1 };
}
default:
throw new Error('unreachable');
}
}