Skip to content

Commit

Permalink
feat: sane eslint config
Browse files Browse the repository at this point in the history
  • Loading branch information
itschip committed Nov 19, 2023
1 parent 8f30f24 commit d90c175
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 61 deletions.
18 changes: 18 additions & 0 deletions web/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
root: true,
env: { browser: true, es2020: true },
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended",
],
ignorePatterns: ["dist", ".eslintrc.cjs"],
parser: "@typescript-eslint/parser",
plugins: ["react-refresh"],
rules: {
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
};
5 changes: 5 additions & 0 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@
"devDependencies": {
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@typescript-eslint/eslint-plugin": "^6.11.0",
"@typescript-eslint/parser": "^6.11.0",
"@vitejs/plugin-react": "^4.2.0",
"eslint": "^8.54.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.4",
"typescript": "^5.2.2",
"vite": "^5.0.0"
}
Expand Down
52 changes: 27 additions & 25 deletions web/src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import React, {useState} from 'react';
import './App.css'
import {debugData} from "../utils/debugData";
import {fetchNui} from "../utils/fetchNui";
import React, { useState } from "react";
import "./App.css";
import { debugData } from "../utils/debugData";
import { fetchNui } from "../utils/fetchNui";

// This will set the NUI to visible if we are
// developing in browser
debugData([
{
action: 'setVisible',
action: "setVisible",
data: true,
}
])
},
]);

interface ReturnClientDataCompProps {
data: any
data: unknown;
}

const ReturnClientDataComp: React.FC<ReturnClientDataCompProps> = ({data}) => (
const ReturnClientDataComp: React.FC<ReturnClientDataCompProps> = ({
data,
}) => (
<>
<h5>Returned Data:</h5>
<pre>
<code>
{JSON.stringify(data, null)}
</code>
<code>{JSON.stringify(data, null)}</code>
</pre>
</>
)
);

interface ReturnData {
x: number;
Expand All @@ -34,22 +34,24 @@ interface ReturnData {
}

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

const handleGetClientData = () => {
fetchNui<ReturnData>('getClientData').then(retData => {
console.log('Got return data from client scripts:')
console.dir(retData)
setClientData(retData)
}).catch(e => {
console.error('Setting mock data due to error', e)
setClientData({ x: 500, y: 300, z: 200})
})
}
fetchNui<ReturnData>("getClientData")
.then((retData) => {
console.log("Got return data from client scripts:");
console.dir(retData);
setClientData(retData);
})
.catch((e) => {
console.error("Setting mock data due to error", e);
setClientData({ x: 500, y: 300, z: 200 });
});
};

return (
<div className="nui-wrapper">
<div className='popup-thing'>
<div className="popup-thing">
<div>
<h1>This is the NUI Popup!</h1>
<p>Exit with the escape key</p>
Expand All @@ -59,6 +61,6 @@ const App: React.FC = () => {
</div>
</div>
);
}
};

export default App;
8 changes: 4 additions & 4 deletions web/src/hooks/useNuiEvent.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {MutableRefObject, useEffect, useRef} from "react";
import {noop} from "../utils/misc";
import { MutableRefObject, useEffect, useRef } from "react";
import { noop } from "../utils/misc";

interface NuiMessageData<T = unknown> {
action: string;
Expand All @@ -20,9 +20,9 @@ type NuiHandlerSignature<T> = (data: T) => void;
*
**/

export const useNuiEvent = <T = any>(
export const useNuiEvent = <T = unknown>(
action: string,
handler: (data: T) => void
handler: (data: T) => void,
) => {
const savedHandler: MutableRefObject<NuiHandlerSignature<T>> = useRef(noop);

Expand Down
54 changes: 34 additions & 20 deletions web/src/providers/VisibilityProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import React, {Context, createContext, useContext, useEffect, useState} from "react";
import {useNuiEvent} from "../hooks/useNuiEvent";
import {fetchNui} from "../utils/fetchNui";
import React, {
Context,
createContext,
useContext,
useEffect,
useState,
} from "react";
import { useNuiEvent } from "../hooks/useNuiEvent";
import { fetchNui } from "../utils/fetchNui";
import { isEnvBrowser } from "../utils/misc";

const VisibilityCtx = createContext<VisibilityProviderValue | null>(null)
const VisibilityCtx = createContext<VisibilityProviderValue | null>(null);

interface VisibilityProviderValue {
setVisible: (visible: boolean) => void
visible: boolean
setVisible: (visible: boolean) => void;
visible: boolean;
}

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

useNuiEvent<boolean>('setVisible', setVisible)
useNuiEvent<boolean>("setVisible", setVisible);

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

window.addEventListener("keydown", keyHandler)
window.addEventListener("keydown", keyHandler);

return () => window.removeEventListener("keydown", keyHandler)
}, [visible])
return () => window.removeEventListener("keydown", keyHandler);
}, [visible]);

return (
<VisibilityCtx.Provider
value={{
visible,
setVisible
setVisible,
}}
>
<div style={{ visibility: visible ? 'visible' : 'hidden', height: '100%'}}>
{children}
</div>
</VisibilityCtx.Provider>)
}
<div
style={{ visibility: visible ? "visible" : "hidden", height: "100%" }}
>
{children}
</div>
</VisibilityCtx.Provider>
);
};

export const useVisibility = () => useContext<VisibilityProviderValue>(VisibilityCtx as Context<VisibilityProviderValue>)
export const useVisibility = () =>
useContext<VisibilityProviderValue>(
VisibilityCtx as Context<VisibilityProviderValue>,
);
8 changes: 4 additions & 4 deletions web/src/utils/debugData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isEnvBrowser } from './misc';
import { isEnvBrowser } from "./misc";

interface DebugEvent<T = any> {
interface DebugEvent<T = unknown> {
action: string;
data: T;
}
Expand All @@ -13,11 +13,11 @@ interface DebugEvent<T = any> {
* @param timer - How long until it should trigger (ms)
*/
export const debugData = <P>(events: DebugEvent<P>[], timer = 1000): void => {
if (import.meta.env.MODE === 'development' && isEnvBrowser()) {
if (import.meta.env.MODE === "development" && isEnvBrowser()) {
for (const event of events) {
setTimeout(() => {
window.dispatchEvent(
new MessageEvent('message', {
new MessageEvent("message", {
data: {
action: event.action,
data: event.data,
Expand Down
18 changes: 12 additions & 6 deletions web/src/utils/fetchNui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,28 @@ import { isEnvBrowser } from "./misc";
* @return returnData - A promise for the data sent back by the NuiCallbacks CB argument
*/

export async function fetchNui<T = any>(eventName: string, data?: any, mockData?: T): Promise<T> {
export async function fetchNui<T = unknown>(
eventName: string,
data?: unknown,
mockData?: T,
): Promise<T> {
const options = {
method: 'post',
method: "post",
headers: {
'Content-Type': 'application/json; charset=UTF-8',
"Content-Type": "application/json; charset=UTF-8",
},
body: JSON.stringify(data),
};

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

const resourceName = (window as any).GetParentResourceName ? (window as any).GetParentResourceName() : 'nui-frame-app';
const resourceName = (window as any).GetParentResourceName
? (window as any).GetParentResourceName()
: "nui-frame-app";

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

const respFormatted = await resp.json()
const respFormatted = await resp.json();

return respFormatted
return respFormatted;
}
4 changes: 2 additions & 2 deletions web/src/utils/misc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Will return whether the current environment is in a regular browser
// and not CEF
export const isEnvBrowser = (): boolean => !(window as any).invokeNative
export const isEnvBrowser = (): boolean => !(window as any).invokeNative;

// Basic no operation function
export const noop = () => {}
export const noop = () => {};

0 comments on commit d90c175

Please sign in to comment.