Skip to content

Commit d90c175

Browse files
committed
feat: sane eslint config
1 parent 8f30f24 commit d90c175

File tree

8 files changed

+106
-61
lines changed

8 files changed

+106
-61
lines changed

web/.eslintrc.cjs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
root: true,
3+
env: { browser: true, es2020: true },
4+
extends: [
5+
"eslint:recommended",
6+
"plugin:@typescript-eslint/recommended",
7+
"plugin:react-hooks/recommended",
8+
],
9+
ignorePatterns: ["dist", ".eslintrc.cjs"],
10+
parser: "@typescript-eslint/parser",
11+
plugins: ["react-refresh"],
12+
rules: {
13+
"react-refresh/only-export-components": [
14+
"warn",
15+
{ allowConstantExport: true },
16+
],
17+
},
18+
};

web/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
"devDependencies": {
1818
"@types/react": "^18.2.37",
1919
"@types/react-dom": "^18.2.15",
20+
"@typescript-eslint/eslint-plugin": "^6.11.0",
21+
"@typescript-eslint/parser": "^6.11.0",
2022
"@vitejs/plugin-react": "^4.2.0",
23+
"eslint": "^8.54.0",
24+
"eslint-plugin-react-hooks": "^4.6.0",
25+
"eslint-plugin-react-refresh": "^0.4.4",
2126
"typescript": "^5.2.2",
2227
"vite": "^5.0.0"
2328
}

web/src/components/App.tsx

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
import React, {useState} from 'react';
2-
import './App.css'
3-
import {debugData} from "../utils/debugData";
4-
import {fetchNui} from "../utils/fetchNui";
1+
import React, { useState } from "react";
2+
import "./App.css";
3+
import { debugData } from "../utils/debugData";
4+
import { fetchNui } from "../utils/fetchNui";
55

66
// This will set the NUI to visible if we are
77
// developing in browser
88
debugData([
99
{
10-
action: 'setVisible',
10+
action: "setVisible",
1111
data: true,
12-
}
13-
])
12+
},
13+
]);
1414

1515
interface ReturnClientDataCompProps {
16-
data: any
16+
data: unknown;
1717
}
1818

19-
const ReturnClientDataComp: React.FC<ReturnClientDataCompProps> = ({data}) => (
19+
const ReturnClientDataComp: React.FC<ReturnClientDataCompProps> = ({
20+
data,
21+
}) => (
2022
<>
2123
<h5>Returned Data:</h5>
2224
<pre>
23-
<code>
24-
{JSON.stringify(data, null)}
25-
</code>
25+
<code>{JSON.stringify(data, null)}</code>
2626
</pre>
2727
</>
28-
)
28+
);
2929

3030
interface ReturnData {
3131
x: number;
@@ -34,22 +34,24 @@ interface ReturnData {
3434
}
3535

3636
const App: React.FC = () => {
37-
const [clientData, setClientData] = useState<ReturnData | null>(null)
37+
const [clientData, setClientData] = useState<ReturnData | null>(null);
3838

3939
const handleGetClientData = () => {
40-
fetchNui<ReturnData>('getClientData').then(retData => {
41-
console.log('Got return data from client scripts:')
42-
console.dir(retData)
43-
setClientData(retData)
44-
}).catch(e => {
45-
console.error('Setting mock data due to error', e)
46-
setClientData({ x: 500, y: 300, z: 200})
47-
})
48-
}
40+
fetchNui<ReturnData>("getClientData")
41+
.then((retData) => {
42+
console.log("Got return data from client scripts:");
43+
console.dir(retData);
44+
setClientData(retData);
45+
})
46+
.catch((e) => {
47+
console.error("Setting mock data due to error", e);
48+
setClientData({ x: 500, y: 300, z: 200 });
49+
});
50+
};
4951

5052
return (
5153
<div className="nui-wrapper">
52-
<div className='popup-thing'>
54+
<div className="popup-thing">
5355
<div>
5456
<h1>This is the NUI Popup!</h1>
5557
<p>Exit with the escape key</p>
@@ -59,6 +61,6 @@ const App: React.FC = () => {
5961
</div>
6062
</div>
6163
);
62-
}
64+
};
6365

6466
export default App;

web/src/hooks/useNuiEvent.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {MutableRefObject, useEffect, useRef} from "react";
2-
import {noop} from "../utils/misc";
1+
import { MutableRefObject, useEffect, useRef } from "react";
2+
import { noop } from "../utils/misc";
33

44
interface NuiMessageData<T = unknown> {
55
action: string;
@@ -20,9 +20,9 @@ type NuiHandlerSignature<T> = (data: T) => void;
2020
*
2121
**/
2222

23-
export const useNuiEvent = <T = any>(
23+
export const useNuiEvent = <T = unknown>(
2424
action: string,
25-
handler: (data: T) => void
25+
handler: (data: T) => void,
2626
) => {
2727
const savedHandler: MutableRefObject<NuiHandlerSignature<T>> = useRef(noop);
2828

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
1-
import React, {Context, createContext, useContext, useEffect, useState} from "react";
2-
import {useNuiEvent} from "../hooks/useNuiEvent";
3-
import {fetchNui} from "../utils/fetchNui";
1+
import React, {
2+
Context,
3+
createContext,
4+
useContext,
5+
useEffect,
6+
useState,
7+
} from "react";
8+
import { useNuiEvent } from "../hooks/useNuiEvent";
9+
import { fetchNui } from "../utils/fetchNui";
410
import { isEnvBrowser } from "../utils/misc";
511

6-
const VisibilityCtx = createContext<VisibilityProviderValue | null>(null)
12+
const VisibilityCtx = createContext<VisibilityProviderValue | null>(null);
713

814
interface VisibilityProviderValue {
9-
setVisible: (visible: boolean) => void
10-
visible: boolean
15+
setVisible: (visible: boolean) => void;
16+
visible: boolean;
1117
}
1218

1319
// This should be mounted at the top level of your application, it is currently set to
1420
// apply a CSS visibility value. If this is non-performant, this should be customized.
15-
export const VisibilityProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
16-
const [visible, setVisible] = useState(false)
21+
export const VisibilityProvider: React.FC<{ children: React.ReactNode }> = ({
22+
children,
23+
}) => {
24+
const [visible, setVisible] = useState(false);
1725

18-
useNuiEvent<boolean>('setVisible', setVisible)
26+
useNuiEvent<boolean>("setVisible", setVisible);
1927

2028
// Handle pressing escape/backspace
2129
useEffect(() => {
@@ -27,24 +35,30 @@ export const VisibilityProvider: React.FC<{ children: React.ReactNode }> = ({ ch
2735
if (!isEnvBrowser()) fetchNui("hideFrame");
2836
else setVisible(!visible);
2937
}
30-
}
38+
};
3139

32-
window.addEventListener("keydown", keyHandler)
40+
window.addEventListener("keydown", keyHandler);
3341

34-
return () => window.removeEventListener("keydown", keyHandler)
35-
}, [visible])
42+
return () => window.removeEventListener("keydown", keyHandler);
43+
}, [visible]);
3644

3745
return (
3846
<VisibilityCtx.Provider
3947
value={{
4048
visible,
41-
setVisible
49+
setVisible,
4250
}}
4351
>
44-
<div style={{ visibility: visible ? 'visible' : 'hidden', height: '100%'}}>
45-
{children}
46-
</div>
47-
</VisibilityCtx.Provider>)
48-
}
52+
<div
53+
style={{ visibility: visible ? "visible" : "hidden", height: "100%" }}
54+
>
55+
{children}
56+
</div>
57+
</VisibilityCtx.Provider>
58+
);
59+
};
4960

50-
export const useVisibility = () => useContext<VisibilityProviderValue>(VisibilityCtx as Context<VisibilityProviderValue>)
61+
export const useVisibility = () =>
62+
useContext<VisibilityProviderValue>(
63+
VisibilityCtx as Context<VisibilityProviderValue>,
64+
);

web/src/utils/debugData.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { isEnvBrowser } from './misc';
1+
import { isEnvBrowser } from "./misc";
22

3-
interface DebugEvent<T = any> {
3+
interface DebugEvent<T = unknown> {
44
action: string;
55
data: T;
66
}
@@ -13,11 +13,11 @@ interface DebugEvent<T = any> {
1313
* @param timer - How long until it should trigger (ms)
1414
*/
1515
export const debugData = <P>(events: DebugEvent<P>[], timer = 1000): void => {
16-
if (import.meta.env.MODE === 'development' && isEnvBrowser()) {
16+
if (import.meta.env.MODE === "development" && isEnvBrowser()) {
1717
for (const event of events) {
1818
setTimeout(() => {
1919
window.dispatchEvent(
20-
new MessageEvent('message', {
20+
new MessageEvent("message", {
2121
data: {
2222
action: event.action,
2323
data: event.data,

web/src/utils/fetchNui.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,28 @@ import { isEnvBrowser } from "./misc";
1212
* @return returnData - A promise for the data sent back by the NuiCallbacks CB argument
1313
*/
1414

15-
export async function fetchNui<T = any>(eventName: string, data?: any, mockData?: T): Promise<T> {
15+
export async function fetchNui<T = unknown>(
16+
eventName: string,
17+
data?: unknown,
18+
mockData?: T,
19+
): Promise<T> {
1620
const options = {
17-
method: 'post',
21+
method: "post",
1822
headers: {
19-
'Content-Type': 'application/json; charset=UTF-8',
23+
"Content-Type": "application/json; charset=UTF-8",
2024
},
2125
body: JSON.stringify(data),
2226
};
2327

2428
if (isEnvBrowser() && mockData) return mockData;
2529

26-
const resourceName = (window as any).GetParentResourceName ? (window as any).GetParentResourceName() : 'nui-frame-app';
30+
const resourceName = (window as any).GetParentResourceName
31+
? (window as any).GetParentResourceName()
32+
: "nui-frame-app";
2733

2834
const resp = await fetch(`https://${resourceName}/${eventName}`, options);
2935

30-
const respFormatted = await resp.json()
36+
const respFormatted = await resp.json();
3137

32-
return respFormatted
38+
return respFormatted;
3339
}

web/src/utils/misc.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Will return whether the current environment is in a regular browser
22
// and not CEF
3-
export const isEnvBrowser = (): boolean => !(window as any).invokeNative
3+
export const isEnvBrowser = (): boolean => !(window as any).invokeNative;
44

55
// Basic no operation function
6-
export const noop = () => {}
6+
export const noop = () => {};

0 commit comments

Comments
 (0)