procon_bypass_man-web 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ProconBypassMan
4
4
  module Web
5
- VERSION = "0.1.0"
5
+ VERSION = "0.1.1"
6
6
  end
7
7
  end
@@ -1,7 +1,7 @@
1
1
  /** @jsx jsx */
2
2
 
3
3
  import { jsx, css } from '@emotion/react'
4
- import React, { useState, useContext } from "react";
4
+ import React, { useState, useReducer, useContext } from "react";
5
5
  import { Button } from "../types/button";
6
6
  import { ButtonState } from "./../lib/button_state";
7
7
  import { ButtonsModal } from "./buttons_modal";
@@ -18,11 +18,11 @@ type ButtonMenuProp = {
18
18
  };
19
19
 
20
20
  const ButtonMenu = ({ name, layerKey, buttonValue, layersDispatch }: ButtonMenuProp) => {
21
- const flipRadioName = `${layerKey}_button_menu_${name}`;
22
21
  const buttonState = new ButtonState(name, buttonValue.flip, buttonValue.remap);
23
22
 
24
23
  // for modal
25
- const [openModal, setOpenModal] = useState(false)
24
+ const [isOpenModal, toggleModal] = useReducer((m) => { return !m; }, false);
25
+
26
26
  const [modalCallbackOnSubmit, setModalCallbackOnSubmit] = useState(undefined as any)
27
27
  const [modalCloseCallback, setModalCloseCallback] = useState(undefined as any)
28
28
  const [modalTitle, setModalTitle] = useState("")
@@ -49,11 +49,11 @@ const ButtonMenu = ({ name, layerKey, buttonValue, layersDispatch }: ButtonMenuP
49
49
  layersDispatch({ type: flipIfPressedSomeButtonsType, payload: { layerKey: layerKey, button: name, targetButtons: bs }});
50
50
  }
51
51
  const openIfPressedSomeButtonsModal = (e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent<HTMLInputElement>) => {
52
- setOpenModal(true)
52
+ toggleModal();
53
53
  setModalTitle("特定のキーを押したときだけ")
54
54
  setModalPrefillButtons(flipIfPressedSomeButtons);
55
55
  setModalCallbackOnSubmit(() => setFlipIfPressedSomeButtonsWithPersistence);
56
- setModalCloseCallback(() => setOpenModal);
56
+ setModalCloseCallback(() => toggleModal);
57
57
  }
58
58
 
59
59
  // 無視
@@ -62,11 +62,11 @@ const ButtonMenu = ({ name, layerKey, buttonValue, layersDispatch }: ButtonMenuP
62
62
  layersDispatch({ type: ignoreButtonsInFlipingType, payload: { layerKey: layerKey, button: name, targetButtons: bs }});
63
63
  }
64
64
  const handleIgnoreButton = (e: React.ChangeEvent<HTMLInputElement>) => {
65
- setOpenModal(true)
65
+ toggleModal();
66
66
  setModalTitle("連打中は特定のボタンの入力を無視する")
67
67
  setModalPrefillButtons(buttonValue.flip?.force_neutral || [] as Array<Button>);
68
68
  setModalCallbackOnSubmit(() => setIgnoreButtonsOnFlipingWithPersistence);
69
- setModalCloseCallback(() => setOpenModal);
69
+ setModalCloseCallback(() => toggleModal);
70
70
  };
71
71
 
72
72
  // リマップ
@@ -74,11 +74,11 @@ const ButtonMenu = ({ name, layerKey, buttonValue, layersDispatch }: ButtonMenuP
74
74
  layersDispatch({ type: remapType, payload: { layerKey: layerKey, button: name, targetButtons: bs }});
75
75
  }
76
76
  const handleRemapButton = (e: React.ChangeEvent<HTMLInputElement>) => {
77
- setOpenModal(true)
77
+ toggleModal();
78
78
  setModalTitle("リマップ")
79
79
  setModalPrefillButtons(buttonValue.remap?.to || []);
80
80
  setModalCallbackOnSubmit(() => setRemapButtonsWithPersistence);
81
- setModalCloseCallback(() => setOpenModal);
81
+ setModalCloseCallback(() => toggleModal);
82
82
  };
83
83
 
84
84
  return(
@@ -91,13 +91,13 @@ const ButtonMenu = ({ name, layerKey, buttonValue, layersDispatch }: ButtonMenuP
91
91
  <input type="radio" onChange={openIfPressedSomeButtonsModal} onClick={openIfPressedSomeButtonsModal} checked={buttonState.isFlipIfPressedSomeButtons()}/>
92
92
  特定のキーを押したときだけ連打する{flipIfPressedSomeButtons.length > 0 && `(${flipIfPressedSomeButtons.join(", ")})`}
93
93
  </label>
94
- </fieldset>
95
94
 
96
- <fieldset><legend><strong>連打オプション</strong></legend>
97
- <label>
98
- <input type="checkbox" onChange={handleIgnoreButton} checked={forceNeutralButtons.length > 0} disabled={buttonState.isDisabledFlip()} />
99
- 連打中は特定のボタンの入力を無視する{forceNeutralButtons.length > 0 && `(${forceNeutralButtons.join(", ")})`}
100
- </label>
95
+ <fieldset><legend><strong>連打オプション</strong></legend>
96
+ <label>
97
+ <input type="checkbox" onChange={handleIgnoreButton} checked={forceNeutralButtons.length > 0} disabled={buttonState.isDisabledFlip()} />
98
+ 連打中は特定のボタンの入力を無視する{forceNeutralButtons.length > 0 && `(${forceNeutralButtons.join(", ")})`}
99
+ </label>
100
+ </fieldset>
101
101
  </fieldset>
102
102
 
103
103
  <fieldset><legend><strong>リマップ設定</strong></legend>
@@ -107,7 +107,7 @@ const ButtonMenu = ({ name, layerKey, buttonValue, layersDispatch }: ButtonMenuP
107
107
  </label>
108
108
  </fieldset>
109
109
  <div css={css`position: relative;`}>
110
- {openModal && <ButtonsModal callbackOnSubmit={modalCallbackOnSubmit} callbackOnClose={modalCloseCallback} title={modalTitle} prefill={modalPrefillButtons} positionOnShown={"relative"} />}
110
+ {isOpenModal && <ButtonsModal callbackOnSubmit={modalCallbackOnSubmit} callbackOnClose={modalCloseCallback} title={modalTitle} prefill={modalPrefillButtons} positionOnShown={"relative"} />}
111
111
  </div>
112
112
  </>
113
113
  )
@@ -119,24 +119,24 @@ type Prop = {
119
119
  };
120
120
 
121
121
  export const ButtonSetting: React.FC<Prop> = ({ name, layerKey }) => {
122
- const settingContext = useContext(ButtonsSettingContext);
122
+ const { layersDispatch, layers } = useContext(ButtonsSettingContext);
123
123
  const handleToggle = () => {
124
124
  if(isOpenMenu()) { // 閉じる
125
- settingContext.layersDispatch({ type: closeMenuType, payload: { layerKey: layerKey, button: name }});
125
+ layersDispatch({ type: closeMenuType, payload: { layerKey: layerKey, button: name }});
126
126
  } else { // 開く
127
- settingContext.layersDispatch({ type: openMenuType, payload: { layerKey: layerKey, button: name }});
127
+ layersDispatch({ type: openMenuType, payload: { layerKey: layerKey, button: name }});
128
128
  }
129
129
  }
130
130
 
131
131
  const isOpenMenu = () => {
132
- return settingContext.layers[layerKey][name].open;
132
+ return layers[layerKey][name].open;
133
133
  }
134
- const buttonValue = settingContext.layers[layerKey][name] || {} as ButtonInLayer;
134
+ const buttonValue = layers[layerKey][name] || {} as ButtonInLayer;
135
135
 
136
136
  return (
137
137
  <>
138
138
  <label><input type="checkbox" checked={isOpenMenu()} onChange={handleToggle}/>{name}</label>
139
- {isOpenMenu() && <ButtonMenu name={name} layerKey={layerKey} buttonValue={buttonValue} layersDispatch={settingContext.layersDispatch} />}
139
+ {isOpenMenu() && <ButtonMenu name={name} layerKey={layerKey} buttonValue={buttonValue} layersDispatch={layersDispatch} />}
140
140
  </>
141
141
  );
142
142
  };
@@ -3,7 +3,7 @@
3
3
  import { jsx, css } from '@emotion/react'
4
4
  import React, { useState, useEffect, useContext } from "react";
5
5
  import { ButtonsSettingContext, } from "./../contexts/buttons_setting";
6
- import { Plugin, PluginBody, AvailablePlugins } from "../types/plugin";
6
+ import { Plugin, PluginBody, AvailablePlugins, MacroNameMap } from "../types/plugin";
7
7
  import { installMacroType, uninstallMacroType } from "../reducers/layer_reducer";
8
8
 
9
9
  const macroClassNamespaces = AvailablePlugins.map((v) => {
@@ -34,7 +34,7 @@ export const InstallableMacro = ({ classNamespace }: Props) => {
34
34
  }
35
35
  return(
36
36
  <>
37
- <input type="checkbox" onChange={handleClick} checked={isChecked(classNamespace)} /> {classNamespace}
37
+ <input type="checkbox" onChange={handleClick} checked={isChecked(classNamespace)} /> {MacroNameMap[classNamespace]}
38
38
  </>
39
39
  )
40
40
  }
@@ -3,7 +3,7 @@
3
3
  import { jsx, css } from '@emotion/react'
4
4
  import React, { useState, useEffect, useContext } from "react";
5
5
  import { ButtonsSettingContext, } from "./../contexts/buttons_setting";
6
- import { Plugin, PluginBody, AvailablePlugins } from "../types/plugin";
6
+ import { Plugin, PluginBody, AvailablePlugins, ModeNameMap } from "../types/plugin";
7
7
  import { installModeType, uninstallModeType } from "../reducers/layer_reducer";
8
8
 
9
9
  const modeClassNamespaces = AvailablePlugins.map((v) => {
@@ -17,27 +17,29 @@ const modeClassNamespaces = AvailablePlugins.map((v) => {
17
17
  }).flat().flat();
18
18
 
19
19
  type Props = {
20
- classNamespace: string;
20
+ modeKey: string;
21
21
  };
22
- export const InstallableMode = ({ classNamespace }: Props) => {
22
+ export const InstallableMode = ({ modeKey }: Props) => {
23
+ const modeName = ModeNameMap[modeKey];
23
24
  const { layers, layersDispatch } = useContext(ButtonsSettingContext);
24
25
  const isChecked = (name: string) => {
25
26
  return layers.installed_modes[name] || false;
26
27
  }
27
28
  const handleClick = (e: React.ChangeEvent<HTMLInputElement>) => {
28
- if(isChecked(classNamespace)) {
29
- layersDispatch({ type: uninstallModeType, payload: { installed_mode: classNamespace }});
29
+ if(isChecked(modeKey)) {
30
+ layersDispatch({ type: uninstallModeType, payload: { installed_mode: modeKey }});
30
31
  } else {
31
- layersDispatch({ type: installModeType, payload: { installed_mode: classNamespace }});
32
+ layersDispatch({ type: installModeType, payload: { installed_mode: modeKey }});
32
33
  }
33
34
  }
34
35
  return(
35
36
  <div>
36
- <input type="checkbox" onChange={handleClick} checked={isChecked(classNamespace)} />{classNamespace}
37
+ <input type="checkbox" onChange={handleClick} checked={isChecked(modeKey)} />{modeName}
37
38
  </div>
38
39
  )
39
40
  }
40
41
 
42
+ console.log("modeClassNamespaces: ", modeClassNamespaces)
41
43
  export const InstallableModes = () => {
42
44
  return(
43
45
  <>
@@ -46,7 +48,7 @@ export const InstallableModes = () => {
46
48
  return(
47
49
  <div key={i}>
48
50
  <label>
49
- <InstallableMode classNamespace={classNamespace} />
51
+ <InstallableMode modeKey={classNamespace} />
50
52
  </label>
51
53
  </div>
52
54
  );
@@ -1,7 +1,7 @@
1
1
  /** @jsx jsx */
2
2
 
3
3
  import { jsx, css } from '@emotion/react'
4
- import React, { useState, useContext } from "react";
4
+ import React, { useState, useReducer, useContext } from "react";
5
5
  import { ButtonsSettingContext } from "./../contexts/buttons_setting";
6
6
  import { LayerKey } from "../types/layer_key";
7
7
  import { Button } from "../types/button";
@@ -17,7 +17,7 @@ type MacroSettingProps = {
17
17
  const MacroSetting = ({ macro, layerKey }: MacroSettingProps) => {
18
18
  const { layersDispatch } = useContext(ButtonsSettingContext);
19
19
  // for modal
20
- const [openModal, setOpenModal] = useState(false)
20
+ const [isOpenModal, toggleModal] = useReducer((m) => { return !m; }, false);
21
21
  const [modalCallbackOnSubmit, setModalCallbackOnSubmit] = useState(undefined as any)
22
22
  const [modalCloseCallback, setModalCloseCallback] = useState(undefined as any)
23
23
  const [modalTitle, setModalTitle] = useState("")
@@ -28,11 +28,11 @@ const MacroSetting = ({ macro, layerKey }: MacroSettingProps) => {
28
28
  layersDispatch({ type: applyMacroType, payload: { layerKey: layerKey, macro: macro }});
29
29
  }
30
30
  const handleClick = (e: React.ChangeEvent<HTMLInputElement>) => {
31
- setOpenModal(true)
31
+ toggleModal();
32
32
  setModalTitle("発動キーの設定")
33
33
  setModalPrefillButtons(macro.if_pressed);
34
34
  setModalCallbackOnSubmit(() => setButtonsForModal);
35
- setModalCloseCallback(() => setOpenModal);
35
+ setModalCloseCallback(() => toggleModal);
36
36
  }
37
37
  const isEnable = macro.if_pressed.length > 0;
38
38
 
@@ -47,7 +47,7 @@ const MacroSetting = ({ macro, layerKey }: MacroSettingProps) => {
47
47
  {isEnable && `${macro.if_pressed.join(", ")}で発動`}
48
48
  </li>
49
49
  <div css={css`position: relative;`}>
50
- {openModal && <ButtonsModal callbackOnSubmit={modalCallbackOnSubmit} callbackOnClose={modalCloseCallback} title={modalTitle} prefill={macro.if_pressed} positionOnShown={"relative"} />}
50
+ {isOpenModal && <ButtonsModal callbackOnSubmit={modalCallbackOnSubmit} callbackOnClose={modalCloseCallback} title={modalTitle} prefill={macro.if_pressed} positionOnShown={"relative"} />}
51
51
  </div>
52
52
  </>
53
53
  )
@@ -42,7 +42,6 @@ export const ModeSettings = ({ layerKey }:ListProps) => {
42
42
  }, [] as Array<StructMode>);
43
43
  modes.unshift({ name: "disable" } as StructMode);
44
44
 
45
- // const hasSomeModes = layers.modes.length > 1;
46
45
  const hasSomeModes = modes.length > 1;
47
46
 
48
47
  return(
@@ -0,0 +1,38 @@
1
+ /** @jsx jsx */
2
+
3
+ import { jsx, css } from '@emotion/react'
4
+ import React, { Component, ErrorInfo, ReactNode } from "react";
5
+
6
+ interface Props {
7
+ children: ReactNode;
8
+ }
9
+
10
+ interface State {
11
+ hasError: boolean;
12
+ }
13
+
14
+ // https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/error_boundaries/
15
+ class ErrorBoundary extends Component<Props, State> {
16
+ public state: State = {
17
+ hasError: false
18
+ };
19
+
20
+ public static getDerivedStateFromError(_: Error): State {
21
+ // Update state so the next render will show the fallback UI.
22
+ return { hasError: true };
23
+ }
24
+
25
+ public componentDidCatch(error: Error, errorInfo: ErrorInfo) {
26
+ console.error("Uncaught error:", error, errorInfo);
27
+ }
28
+
29
+ public render() {
30
+ if (this.state.hasError) {
31
+ return <h1>Sorry..there was an error</h1>;
32
+ }
33
+
34
+ return this.props.children;
35
+ }
36
+ }
37
+
38
+ export default ErrorBoundary;
@@ -1,7 +1,7 @@
1
1
  /** @jsx jsx */
2
2
 
3
3
  import { jsx, css } from '@emotion/react'
4
- import React, { useState, useEffect, useContext, useRef } from "react";
4
+ import React, { useState, useEffect, useReducer, useContext, useRef } from "react";
5
5
  import { ButtonsSetting } from "../components/buttons_setting";
6
6
  import { Button, buttons } from "../types/button";
7
7
  import { LayerKey, layerKeys } from "../types/layer_key";
@@ -25,7 +25,8 @@ interface LayerRef {
25
25
  };
26
26
 
27
27
  export const ButtonsSettingPage = () => {
28
- const { loaded, setLoaded, layers, layersDispatch, prefixKeys, setPrefixKeys } = useContext(ButtonsSettingContext);
28
+ const [loaded, DidLoad] = useReducer(() => { return true; }, false);
29
+ const { layers, layersDispatch, prefixKeys, setPrefixKeys } = useContext(ButtonsSettingContext);
29
30
  const [selectedLayer, setSelectedLayer] = useState<LayerKey>("up");
30
31
  const layerRefs = layerKeys.map((l) => ({} as LayerRef));
31
32
  const [initializedSetting, setInitializedSetting] = useState({} as ButtonsSettingType)
@@ -117,7 +118,7 @@ export const ButtonsSettingPage = () => {
117
118
  })
118
119
  }
119
120
 
120
- setPrefixKeys(response.data.setting.prefix_keys_for_changing_layer);
121
+ setPrefixKeys(response.data.setting.prefix_keys_for_changing_layer.sort());
121
122
  const layers = layerKeys.reduce((a, key) => {
122
123
  a[key] = response.data.setting_group_by_button.layers[key];
123
124
  return a;
@@ -173,7 +174,7 @@ export const ButtonsSettingPage = () => {
173
174
  });
174
175
  });
175
176
 
176
- setLoaded(true);
177
+ DidLoad();
177
178
  }).catch(function (error) {
178
179
  if (error.response.status === 404) {
179
180
  setInfoMessage("設定ファイルのパスが未設定です")
@@ -181,7 +182,6 @@ export const ButtonsSettingPage = () => {
181
182
  console.log("想定外のエラーです");
182
183
  }
183
184
  })
184
-
185
185
  }, [loaded]);
186
186
 
187
187
  const layersTabStyle = () => {
@@ -219,20 +219,22 @@ export const ButtonsSettingPage = () => {
219
219
  };
220
220
  }
221
221
  const handlePrefixKeysField = () => {
222
- setOpenModal(true)
222
+ toggleModal();
223
223
  setModalTitle("キープレフィックスの変更")
224
224
  setModalPrefillButtons(prefixKeys);
225
225
  setModalCallbackOnSubmit(() => setPrefixKeys);
226
- setModalCloseCallback(() => setOpenModal);
226
+ setModalCloseCallback(() => toggleModal);
227
227
  }
228
228
 
229
229
  // for modal
230
- const [openModal, setOpenModal] = useState(false)
230
+ const [isOpenModal, toggleModal] = useReducer(((m) => { return !m; }), false);
231
231
  const [modalCallbackOnSubmit, setModalCallbackOnSubmit] = useState(undefined as any)
232
232
  const [modalCloseCallback, setModalCloseCallback] = useState(undefined as any)
233
233
  const [modalTitle, setModalTitle] = useState("")
234
234
  const [modalPrefillButtons, setModalPrefillButtons] = useState<Array<Button>>([])
235
235
 
236
+ if(!loaded) { return null; };
237
+
236
238
  return(
237
239
  <>
238
240
  <div css={css`display: table`}>
@@ -243,15 +245,18 @@ export const ButtonsSettingPage = () => {
243
245
  </div>
244
246
 
245
247
  <h3>インストール可能なマクロ</h3>
246
- {loaded && <InstallableMacros />}
248
+ {<InstallableMacros />}
247
249
 
248
250
  <h3>インストール可能なモード</h3>
249
- {loaded && <InstallableModes />}
251
+ {<InstallableModes />}
252
+
253
+ <h3>インストール可能なマクロ</h3>
254
+ {loaded && <InstallableMacros />}
250
255
 
251
256
  <h3>設定中のプレフィックスキー</h3>
252
257
  <div css={css`position: relative; margin-bottom: 20px;`}>
253
258
  <input type="text" value={prefixKeys.join(", ")} readOnly={true} onClick={handlePrefixKeysField} />
254
- {openModal && <ButtonsModal callbackOnSubmit={modalCallbackOnSubmit} callbackOnClose={modalCloseCallback} title={modalTitle} prefill={modalPrefillButtons} positionOnShown={"stay"} />}
259
+ {isOpenModal && <ButtonsModal callbackOnSubmit={modalCallbackOnSubmit} callbackOnClose={modalCloseCallback} title={modalTitle} prefill={modalPrefillButtons} positionOnShown={"stay"} />}
255
260
  </div>
256
261
  </div>
257
262
  <div css={css`display: table-cell`}>
@@ -260,7 +265,7 @@ export const ButtonsSettingPage = () => {
260
265
  <a href="#" onClick={applySetting}>変更した設定でsetting.ymlへ上書きする</a>
261
266
  <div>{infoMessage}</div>
262
267
  <ul>
263
- {loaded && changes().map((c, i) => <li key={i}>{c}</li>)}
268
+ {changes().map((c, i) => <li key={i}>{c}</li>)}
264
269
  </ul>
265
270
  </div>
266
271
  </div>
@@ -274,8 +279,7 @@ export const ButtonsSettingPage = () => {
274
279
  ))}
275
280
  </ul>
276
281
 
277
- {loaded && layerKeys.map((l, index) => (<ButtonsSetting key={index} layerKey={l} layerRef={layerRefs[index]} />))}
278
- {!loaded && "loading..."}
282
+ {layerKeys.map((l, index) => (<ButtonsSetting key={index} layerKey={l} layerRef={layerRefs[index]} />))}
279
283
  </>
280
284
  )
281
285
  }
data/src/pages/top.tsx CHANGED
@@ -17,8 +17,9 @@ import { ButtonsSettingContext } from "./../contexts/buttons_setting";
17
17
  import { ButtonsInLayer, Layers, ButtonsSettingType } from "../types/buttons_setting_type";
18
18
  import { buttons, Button } from "../types/button";
19
19
  import { LayerReducer } from "../reducers/layer_reducer";
20
+ import ErrorBoundary from "../lib/error_boundary";
20
21
 
21
- const ButtonsSettingProfile: React.FC = ({children}) => {
22
+ const ButtonsSettingProvider: React.FC = ({children}) => {
22
23
  const initLayers: Layers = {
23
24
  up: buttons.reduce((a, i) => { a[i] = { open: false }; return a }, {} as ButtonsInLayer),
24
25
  right: buttons.reduce((a, i) => { a[i] = { open: false }; return a }, {} as ButtonsInLayer),
@@ -28,11 +29,8 @@ const ButtonsSettingProfile: React.FC = ({children}) => {
28
29
  installed_modes: {},
29
30
  }
30
31
  const [prefixKeys, setPrefixKeys] = useState([]);
31
- const [loaded, setLoaded] = useState(false);
32
32
  const [layers, layersDispatch] = useReducer(LayerReducer, initLayers as Layers);
33
33
  const value = {
34
- loaded,
35
- setLoaded,
36
34
  layers,
37
35
  prefixKeys,
38
36
  setPrefixKeys,
@@ -83,18 +81,27 @@ export const Top: React.FC = () => {
83
81
  </li>
84
82
  </ul>
85
83
  </nav>
84
+
86
85
  <Switch>
87
86
  <Route exact path="/" >
88
87
  <Home />
89
88
  </Route>
90
89
  <Route path="/setting">
91
- <GlobalSetting />
90
+ <ErrorBoundary>
91
+ <GlobalSetting />
92
+ </ErrorBoundary>
92
93
  </Route>
93
94
  <Route path="/pbm">
94
- <BpmPage />
95
+ <ErrorBoundary>
96
+ <BpmPage />
97
+ </ErrorBoundary>
95
98
  </Route>
96
99
  <Route path="/buttons_setting">
97
- <ButtonsSettingProfile><ButtonsSettingPage /></ButtonsSettingProfile>
100
+ <ErrorBoundary>
101
+ <ButtonsSettingProvider>
102
+ <ButtonsSettingPage />
103
+ </ButtonsSettingProvider>
104
+ </ErrorBoundary>
98
105
  </Route>
99
106
  <Route path="/recoding_mode">
100
107
  <RecodingModePage />
data/src/types/plugin.ts CHANGED
@@ -19,6 +19,9 @@ export const AvailablePlugins = [
19
19
  ],
20
20
  macros: [
21
21
  { display_name: "splatoon2.fast_return", class_namespace: "ProconBypassMan::Splatoon2::Macro::FastReturn" },
22
+ { display_name: "splatoon2.jump_right", class_namespace: "ProconBypassMan::Splatoon2::Macro::JumpToRightKey" },
23
+ { display_name: "splatoon2.jump_up", class_namespace: "ProconBypassMan::Splatoon2::Macro::JumpToUpKey" },
24
+ { display_name: "splatoon2.jump_left", class_namespace: "ProconBypassMan::Splatoon2::Macro::JumpToLeftKey" },
22
25
  ],
23
26
  }
24
27
  } as Plugin,