diff --git a/packages/app/src/app/pages/Sandbox/QuickActions/index.js b/packages/app/src/app/pages/Sandbox/QuickActions/index.js deleted file mode 100644 index ba8fd690f65..00000000000 --- a/packages/app/src/app/pages/Sandbox/QuickActions/index.js +++ /dev/null @@ -1,182 +0,0 @@ -import React from 'react'; -import { inject, observer } from 'app/componentConnectors'; -import Downshift from 'downshift'; -import genie from 'geniejs'; - -import { ESC } from '@codesandbox/common/lib/utils/keycodes'; - -import Input from '@codesandbox/common/lib/components/Input'; -import Keys from './Keys'; - -import { - Container, - Items, - InputContainer, - Entry, - Title, - Keybindings, -} from './elements'; - -class QuickActionsComponent extends React.Component { - // we'll just keep track of what the user changes the inputValue to be - // so when the user makes a wish we can provide that info to genie - inputValue = ''; - - updateGenie = () => { - const { keybindings } = this.props.store.preferences; - const { signals } = this.props; - - Object.keys(keybindings).forEach(bindingKey => { - const quickAction = keybindings[bindingKey]; - - genie({ - magicWords: `${quickAction.type}: ${quickAction.title}`, - id: bindingKey, - action: () => { - const signalPath = quickAction.signal.split('.'); - const signal = signalPath.reduce( - (currentSignal, key) => currentSignal[key], - signals - ); - const payload = - typeof quickAction.payload === 'function' - ? quickAction.payload(this.props.store) - : quickAction.payload || {}; - signal(payload); - }, - }); - }); - }; - - componentDidMount() { - this.updateGenie(); - this.loadGenie(); - } - - componentDidUpdate() { - this.updateGenie(); - } - - getItems = value => genie.getMatchingWishes(value); - - handleKeyUp = e => { - if (e.keyCode === ESC) { - this.closeQuickActions(); - } - }; - - closeQuickActions = () => { - this.props.signals.editor.quickActionsClosed(); - }; - - onChange = item => { - genie.makeWish(item, this.inputValue); - this.persistGenie(); - this.closeQuickActions(); - }; - - persistGenie() { - const { enteredMagicWords } = genie.options(); - window.localStorage.setItem('genie', JSON.stringify({ enteredMagicWords })); - } - - loadGenie() { - try { - const { enteredMagicWords } = JSON.parse( - window.localStorage.getItem('genie') - ); - genie.options({ enteredMagicWords }); - } catch (error) { - // it may not exist in localStorage yet, or the JSON was malformed somehow - // so we'll persist it to update localStorage so it doesn't throw an error - // next time the page is loaded. - this.persistGenie(); - } - } - - itemToString = item => item && item.magicWords.join(', '); - - render() { - if (!this.props.store.editor.quickActionsOpen) { - return null; - } - - const { keybindings } = this.props.store.preferences; - - return ( - - - {({ - getInputProps, - getItemProps, - selectedItem, - inputValue, - highlightedIndex, - }) => { - const inputProps = getInputProps({ - onChange: ev => { - this.inputValue = ev.target.value; - }, - innerRef: el => el && el.focus(), - onKeyUp: this.handleKeyUp, - // Timeout so the fuzzy handler can still select the module - onBlur: () => setTimeout(this.closeQuickActions, 100), - }); - return ( -
- - - - - - {this.getItems(inputValue).map((item, index) => ( - - - {keybindings[item.id].type}:{' '} - {keybindings[item.id].title} - - - {keybindings[item.id].bindings && - keybindings[item.id].bindings[0] && ( - - - {keybindings[item.id].bindings.length === 2 && - keybindings[item.id].bindings[1] && - keybindings[item.id].bindings[1].length && ( - <> - {' - '} - - - )} - - )} - - ))} - -
- ); - }} -
-
- ); - } -} - -export const QuickActions = inject('signals', 'store')( - observer(QuickActionsComponent) -); diff --git a/packages/app/src/app/pages/Sandbox/QuickActions/index.tsx b/packages/app/src/app/pages/Sandbox/QuickActions/index.tsx new file mode 100644 index 00000000000..fa757432301 --- /dev/null +++ b/packages/app/src/app/pages/Sandbox/QuickActions/index.tsx @@ -0,0 +1,178 @@ +import React, { useEffect, useCallback } from 'react'; +import Downshift from 'downshift'; +import genie from 'geniejs'; + +import { useOvermind } from 'app/overmind'; + +import { ESC } from '@codesandbox/common/lib/utils/keycodes'; + +import Input from '@codesandbox/common/lib/components/Input'; +import Keys from './Keys'; + +import { + Container, + Items, + InputContainer, + Entry, + Title, + Keybindings, +} from './elements'; + +export const QuickActions: React.FunctionComponent = () => { + const { + state, + state: { + preferences: { keybindings }, + editor: { quickActionsOpen }, + }, + actions, + actions: { editor }, + } = useOvermind(); + + const loadGenie = useCallback(() => { + try { + const { enteredMagicWords } = JSON.parse( + window.localStorage.getItem('genie') + ); + genie.options({ enteredMagicWords }); + } catch (error) { + // it may not exist in localStorage yet, or the JSON was malformed somehow + // so we'll persist it to update localStorage so it doesn't throw an error + // next time the page is loaded. + persistGenie(); + } + }, []); + + const updateGenie = useCallback(() => { + Object.keys(keybindings).forEach(bindingKey => { + const { + quickAction: { type, title, signal, payload }, + } = keybindings[bindingKey]; + + genie({ + magicWords: `${type}: ${title}`, + id: bindingKey, + action: () => { + const signalPath = signal.split('.'); + const signalFn = signalPath.reduce( + (currentSignal, key) => currentSignal[key], + actions + ); + const payloadVal = + typeof payload === 'function' ? payload(state) : payload || {}; + signalFn(payloadVal); + }, + }); + }); + }, [actions, keybindings, state]); + + useEffect(() => { + updateGenie(); + loadGenie(); + }, [loadGenie, updateGenie]); + + useEffect(() => { + updateGenie(); + }, [keybindings, updateGenie]); + + if (!quickActionsOpen) { + return null; + } + + const getItems = value => genie.getMatchingWishes(value); + + const handleKeyUp = e => { + if (e.keyCode === ESC) { + closeQuickActions(); + } + }; + + const closeQuickActions = () => { + editor.quickActionsClosed(); + }; + + const persistGenie = () => { + const { enteredMagicWords } = genie.options(); + window.localStorage.setItem('genie', JSON.stringify({ enteredMagicWords })); + }; + + let inputVal = ''; + const onChange = item => { + genie.makeWish(item, inputVal); + persistGenie(); + closeQuickActions(); + }; + + const itemToString = item => item && item.magicWords.join(', '); + + return ( + + + {({ + getInputProps, + getItemProps, + selectedItem, + inputValue, + highlightedIndex, + }) => { + const inputProps = getInputProps({ + onChange: (ev: React.ChangeEvent) => { + inputVal = ev.target.value; + }, + innerRef: (el: any) => el && el.focus(), + onKeyUp: handleKeyUp, + // Timeout so the fuzzy handler can still select the module + onBlur: () => setTimeout(closeQuickActions, 100), + } as any); + return ( +
+ + + + + + {getItems(inputValue).map((item, index) => ( + + + {keybindings[item.id].type}: {keybindings[item.id].title} + + + {keybindings[item.id].bindings && + keybindings[item.id].bindings[0] && ( + + + {keybindings[item.id].bindings.length === 2 && + keybindings[item.id].bindings[1] && + keybindings[item.id].bindings[1].length && ( + <> + {' - '} + + + )} + + )} + + ))} + +
+ ); + }} +
+
+ ); +};