Skip to content

Commit a62cec4

Browse files
jyotiarora2610SaraVieira
authored andcommitted
QuickActions refactoring app/src/app/pages/Sandbox/QuickActions… (codesandbox#2817)
* QuickActions refactoring * refactoring to functional components * renamed quickactions to index and fixed imports
1 parent d1c88a1 commit a62cec4

File tree

2 files changed

+178
-182
lines changed

2 files changed

+178
-182
lines changed

packages/app/src/app/pages/Sandbox/QuickActions/index.js

Lines changed: 0 additions & 182 deletions
This file was deleted.
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import React, { useEffect, useCallback } from 'react';
2+
import Downshift from 'downshift';
3+
import genie from 'geniejs';
4+
5+
import { useOvermind } from 'app/overmind';
6+
7+
import { ESC } from '@codesandbox/common/lib/utils/keycodes';
8+
9+
import Input from '@codesandbox/common/lib/components/Input';
10+
import Keys from './Keys';
11+
12+
import {
13+
Container,
14+
Items,
15+
InputContainer,
16+
Entry,
17+
Title,
18+
Keybindings,
19+
} from './elements';
20+
21+
export const QuickActions: React.FunctionComponent = () => {
22+
const {
23+
state,
24+
state: {
25+
preferences: { keybindings },
26+
editor: { quickActionsOpen },
27+
},
28+
actions,
29+
actions: { editor },
30+
} = useOvermind();
31+
32+
const loadGenie = useCallback(() => {
33+
try {
34+
const { enteredMagicWords } = JSON.parse(
35+
window.localStorage.getItem('genie')
36+
);
37+
genie.options({ enteredMagicWords });
38+
} catch (error) {
39+
// it may not exist in localStorage yet, or the JSON was malformed somehow
40+
// so we'll persist it to update localStorage so it doesn't throw an error
41+
// next time the page is loaded.
42+
persistGenie();
43+
}
44+
}, []);
45+
46+
const updateGenie = useCallback(() => {
47+
Object.keys(keybindings).forEach(bindingKey => {
48+
const {
49+
quickAction: { type, title, signal, payload },
50+
} = keybindings[bindingKey];
51+
52+
genie({
53+
magicWords: `${type}: ${title}`,
54+
id: bindingKey,
55+
action: () => {
56+
const signalPath = signal.split('.');
57+
const signalFn = signalPath.reduce(
58+
(currentSignal, key) => currentSignal[key],
59+
actions
60+
);
61+
const payloadVal =
62+
typeof payload === 'function' ? payload(state) : payload || {};
63+
signalFn(payloadVal);
64+
},
65+
});
66+
});
67+
}, [actions, keybindings, state]);
68+
69+
useEffect(() => {
70+
updateGenie();
71+
loadGenie();
72+
}, [loadGenie, updateGenie]);
73+
74+
useEffect(() => {
75+
updateGenie();
76+
}, [keybindings, updateGenie]);
77+
78+
if (!quickActionsOpen) {
79+
return null;
80+
}
81+
82+
const getItems = value => genie.getMatchingWishes(value);
83+
84+
const handleKeyUp = e => {
85+
if (e.keyCode === ESC) {
86+
closeQuickActions();
87+
}
88+
};
89+
90+
const closeQuickActions = () => {
91+
editor.quickActionsClosed();
92+
};
93+
94+
const persistGenie = () => {
95+
const { enteredMagicWords } = genie.options();
96+
window.localStorage.setItem('genie', JSON.stringify({ enteredMagicWords }));
97+
};
98+
99+
let inputVal = '';
100+
const onChange = item => {
101+
genie.makeWish(item, inputVal);
102+
persistGenie();
103+
closeQuickActions();
104+
};
105+
106+
const itemToString = item => item && item.magicWords.join(', ');
107+
108+
return (
109+
<Container>
110+
<Downshift
111+
defaultHighlightedIndex={0}
112+
defaultIsOpen
113+
onChange={onChange}
114+
itemToString={itemToString}
115+
>
116+
{({
117+
getInputProps,
118+
getItemProps,
119+
selectedItem,
120+
inputValue,
121+
highlightedIndex,
122+
}) => {
123+
const inputProps = getInputProps({
124+
onChange: (ev: React.ChangeEvent<HTMLInputElement>) => {
125+
inputVal = ev.target.value;
126+
},
127+
innerRef: (el: any) => el && el.focus(),
128+
onKeyUp: handleKeyUp,
129+
// Timeout so the fuzzy handler can still select the module
130+
onBlur: () => setTimeout(closeQuickActions, 100),
131+
} as any);
132+
return (
133+
<div style={{ width: '100%' }}>
134+
<InputContainer>
135+
<Input {...inputProps} value={inputProps.value || ''} />
136+
</InputContainer>
137+
138+
<Items>
139+
{getItems(inputValue).map((item, index) => (
140+
<Entry
141+
{...getItemProps({
142+
item,
143+
index,
144+
isActive: highlightedIndex === index,
145+
isSelected: selectedItem === item,
146+
})}
147+
key={item.id}
148+
>
149+
<Title>
150+
{keybindings[item.id].type}: {keybindings[item.id].title}
151+
</Title>
152+
153+
{keybindings[item.id].bindings &&
154+
keybindings[item.id].bindings[0] && (
155+
<Keybindings>
156+
<Keys bindings={keybindings[item.id].bindings[0]} />
157+
{keybindings[item.id].bindings.length === 2 &&
158+
keybindings[item.id].bindings[1] &&
159+
keybindings[item.id].bindings[1].length && (
160+
<>
161+
{' - '}
162+
<Keys
163+
bindings={keybindings[item.id].bindings[1]}
164+
/>
165+
</>
166+
)}
167+
</Keybindings>
168+
)}
169+
</Entry>
170+
))}
171+
</Items>
172+
</div>
173+
);
174+
}}
175+
</Downshift>
176+
</Container>
177+
);
178+
};

0 commit comments

Comments
 (0)