diff --git a/locales/en.json b/locales/en.json
index c332031..54d9c83 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -1,5 +1,11 @@
{
"language": "English",
- "ui.close": "Close",
- "ui.confirm": "Confirm"
+ "ui": {
+ "settings": {
+ "title": "Settings",
+ "language": "Language"
+ },
+ "close": "Close",
+ "confirm": "Confirm"
+ }
}
diff --git a/locales/fr.json b/locales/fr.json
index 70abe13..3f6821a 100644
--- a/locales/fr.json
+++ b/locales/fr.json
@@ -1,5 +1,11 @@
{
"language": "Français",
- "ui.close": "Fermer",
- "ui.confirm": "Confirmer"
+ "ui": {
+ "settings": {
+ "title": "Réglages",
+ "language": "Langue"
+ },
+ "close": "Fermer",
+ "confirm": "Confirmer"
+ }
}
diff --git a/resource/locale/client.lua b/resource/locale/client.lua
index 07469c9..f6731e3 100644
--- a/resource/locale/client.lua
+++ b/resource/locale/client.lua
@@ -1,21 +1,42 @@
+local default = { 'en', 'fr', 'de', 'it', 'es', 'pt-BR', 'pl', 'ru', 'ko', 'zh-TW', 'ja', 'es-MX', 'zh-CN' }
local userLocale = GetResourceKvpString('locale')
local function loadLocale(locale, cb)
+ if cb then cb(1) end
local JSON = LoadResourceFile('ox_lib', ('locales/%s.json'):format(locale)) or LoadResourceFile('ox_lib', ('locales/en.json'):format(locale))
- if cb then cb(JSON) end
-
+ SendNUIMessage({
+ action = 'setLocale',
+ data = json.decode(JSON)
+ })
SetResourceKvp('locale', locale)
TriggerEvent('ox_lib:setLocale', locale)
end
RegisterNUICallback('getLocale', loadLocale)
-if not userLocale then
- local default = { 'en', 'fr', 'de', 'it', 'es', 'pt-BR', 'pl', 'ru', 'ko', 'zh-TW', 'ja', 'es-MX', 'zh-CN' }
- userLocale = default[GetCurrentLanguage() + 1]
-end
+RegisterNUICallback('closeSettings', function(_, cb)
+ cb(1)
+ SetNuiFocus(false, false)
+end)
-loadLocale(userLocale)
+if not userLocale then userLocale = default[GetCurrentLanguage() + 1] end
+
+RegisterNUICallback('init', function(_, cb)
+ cb(1)
+ loadLocale(userLocale)
+ SendNUIMessage({ -- Loads the `default` array into select options
+ action = 'loadLocales',
+ data = default
+ })
+end)
+
+RegisterCommand('ox_lib', function()
+ SendNUIMessage({
+ action = 'openSettings',
+ data = GetResourceKvpString('locale') -- Sets the value for language select
+ })
+ SetNuiFocus(true, true)
+end)
RegisterCommand('setlocale', function(_, args, _)
if args?[1] then
diff --git a/web/src/App.tsx b/web/src/App.tsx
index c963b48..c551d72 100644
--- a/web/src/App.tsx
+++ b/web/src/App.tsx
@@ -4,16 +4,21 @@ import Progressbar from "./features/progress/Progressbar";
import TextUI from "./features/textui/TextUI";
import InputDialog from "./features/dialog/InputDialog";
import ContextMenu from "./features/menu/ContextMenu";
+import Settings from "./features/settings";
import { useNuiEvent } from "./hooks/useNuiEvent";
import { setClipboard } from "./utils/setClipboard";
+import { fetchNui } from "./utils/fetchNui";
const App: React.FC = () => {
useNuiEvent("setClipboard", (data: string) => {
setClipboard(data);
});
+ fetchNui("init");
+
return (
<>
+
diff --git a/web/src/features/settings/components/locale.tsx b/web/src/features/settings/components/locale.tsx
new file mode 100644
index 0000000..3f4eca6
--- /dev/null
+++ b/web/src/features/settings/components/locale.tsx
@@ -0,0 +1,38 @@
+import { HStack, Text, Select, Spacer } from "@chakra-ui/react";
+import { useEffect, useState } from "react";
+import { useNuiEvent } from "../../../hooks/useNuiEvent";
+import { useLocales } from "../../../providers/LocaleProvider";
+import { fetchNui } from "../../../utils/fetchNui";
+
+const LocaleSetting: React.FC<{
+ languages: string[];
+ selectValue: string;
+ setSelectValue: React.Dispatch>;
+}> = (props) => {
+ const { locale } = useLocales();
+
+ const handleChange = (e: React.ChangeEvent) => {
+ props.setSelectValue(e.target.value);
+ fetchNui("getLocale", e.target.value);
+ };
+
+ return (
+
+ {locale.ui.settings.language}
+
+
+
+ );
+};
+
+export default LocaleSetting;
diff --git a/web/src/features/settings/index.tsx b/web/src/features/settings/index.tsx
new file mode 100644
index 0000000..ab04d8d
--- /dev/null
+++ b/web/src/features/settings/index.tsx
@@ -0,0 +1,74 @@
+import {
+ Button,
+ Modal,
+ ModalBody,
+ ModalCloseButton,
+ ModalContent,
+ ModalFooter,
+ ModalHeader,
+ ModalOverlay,
+ useDisclosure,
+} from "@chakra-ui/react";
+import LocaleSetting from "./components/locale";
+import { useEffect, useState } from "react";
+import { useNuiEvent } from "../../hooks/useNuiEvent";
+import { debugData } from "../../utils/debugData";
+import { fetchNui } from "../../utils/fetchNui";
+import { useLocales } from "../../providers/LocaleProvider";
+
+debugData([
+ {
+ action: "openSettings",
+ data: true,
+ },
+]);
+
+const Settings: React.FC = () => {
+ const { isOpen, onOpen, onClose } = useDisclosure();
+ const { locale } = useLocales();
+ const [languages, setLanguages] = useState([""]);
+ const [selectValue, setSelectValue] = useState("");
+
+ const closeSettings = () => {
+ onClose();
+ fetchNui("closeSettings");
+ };
+
+ useNuiEvent("loadLocales", (data) => setLanguages(data));
+ useNuiEvent("openSettings", (data: string) => {
+ onOpen();
+ setSelectValue(data);
+ });
+
+ return (
+ <>
+
+
+
+ {locale.ui.settings.title}
+
+
+
+
+
+
+
+
+ >
+ );
+};
+
+export default Settings;
diff --git a/web/src/index.tsx b/web/src/index.tsx
index 4d902bb..6b1276e 100644
--- a/web/src/index.tsx
+++ b/web/src/index.tsx
@@ -11,6 +11,7 @@ import { far } from "@fortawesome/free-regular-svg-icons";
import { fab } from "@fortawesome/free-brands-svg-icons";
import { library } from "@fortawesome/fontawesome-svg-core";
import { isEnvBrowser } from "./utils/misc";
+import LocaleProvider from "./providers/LocaleProvider";
library.add(fas, far, fab);
@@ -33,11 +34,13 @@ debugData([
ReactDOM.render(
-
-
-
-
-
+
+
+
+
+
+
+
,
document.getElementById("root")
);
diff --git a/web/src/providers/LocaleProvider.tsx b/web/src/providers/LocaleProvider.tsx
new file mode 100644
index 0000000..4637666
--- /dev/null
+++ b/web/src/providers/LocaleProvider.tsx
@@ -0,0 +1,87 @@
+import { Context, createContext, useContext, useEffect, useState } from "react";
+import { useNuiEvent } from "../hooks/useNuiEvent";
+import { debugData } from "../utils/debugData";
+
+debugData([
+ {
+ action: "loadLocales",
+ data: [
+ "en",
+ "fr",
+ "de",
+ "it",
+ "es",
+ "pt-BR",
+ "pl",
+ "ru",
+ "ko",
+ "zh-TW",
+ "ja",
+ "es-MX",
+ "zh-CN",
+ ],
+ },
+]);
+
+debugData([
+ {
+ action: "setLocale",
+ data: {
+ language: "English",
+ ui: {
+ settings: {
+ title: "Settings",
+ language: "Language",
+ },
+ close: "Close",
+ confirm: "Confirm",
+ },
+ },
+ },
+]);
+
+interface Locale {
+ language: string;
+ ui: {
+ settings: {
+ title: string;
+ language: string;
+ };
+ close: string;
+ confirm: string;
+ };
+}
+
+interface LocaleContextValue {
+ locale: Locale;
+ setLocale: (locales: Locale) => void;
+}
+
+const LocaleCtx = createContext(null);
+
+const LocaleProvider: React.FC = ({ children }) => {
+ const [locale, setLocale] = useState({
+ language: "",
+ ui: {
+ settings: {
+ title: "",
+ language: "",
+ },
+ close: "",
+ confirm: "",
+ },
+ });
+
+ useNuiEvent("setLocale", async (data: Locale) => setLocale(data));
+
+ return (
+
+ {children}
+
+ );
+};
+
+export default LocaleProvider;
+
+export const useLocales = () =>
+ useContext(LocaleCtx as Context);