1 import PropTypes from 'prop-types';
2 import React from 'react';
4 import SNESSocket from '../helpers/SNESSocket';
6 const context = React.createContext({});
8 export const useSNES = () => React.useContext(context);
10 export const SNESProvider = ({ children }) => {
11 const [enabled, setEnabled] = React.useState(false);
13 const sock = React.useRef(null);
15 const [settings, setSettings] = React.useState({
22 const [status, setStatus] = React.useState({
29 React.useEffect(() => {
35 const tryAttach = () => {
36 const { deviceList } = sock.current;
38 if (deviceList.includes(settings.device)) {
39 device = settings.device;
40 } else if (deviceList.length > 0) {
41 device = deviceList[0];
43 setStatus(s => ({ ...s, device, deviceList }));
45 sock.current.attachDevice(device);
48 sock.current = new SNESSocket(`${settings.proto}://${settings.host}:${settings.port}`);
49 sock.current.onclose = () => {
57 sock.current.onerror = (e) => {
65 sock.current.onopen = () => {
72 sock.current.requestDeviceList(() => {
76 const watchdog = setInterval(() => {
77 if (!sock.current.isOpen()) {
81 if (!sock.current.device) {
82 sock.current.requestDeviceList(() => {
88 clearInterval(watchdog);
91 }, [enabled, settings]);
93 const enable = React.useCallback(() => {
94 setEnabled(prevEnabled => {
95 if (prevEnabled) return true;
100 const disable = React.useCallback(() => {
101 setEnabled(prevEnabled => {
102 if (!prevEnabled) return false;
107 React.useEffect(() => {
108 const savedSettings = localStorage.getItem('snes.settings');
110 setSettings(JSON.parse(savedSettings));
114 const value = React.useMemo(() => {
115 return { disable, enable, enabled, settings, sock, status };
116 }, [disable, enable, enabled, settings, sock, status]);
118 return <context.Provider value={value}>
123 SNESProvider.propTypes = {
124 children: PropTypes.node,