Refactor languages and fix hooks logic bugs.

This commit is contained in:
Marco Rodolfi
2023-01-31 15:27:28 +01:00
parent eaf7239dd1
commit 25e3f84ddd
45 changed files with 777 additions and 335 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ def get_csrf_token():
@middleware
async def csrf_middleware(request, handler):
if str(request.method) == "OPTIONS" or request.headers.get('Authentication') == csrf_token or str(request.rel_url) == "/auth/token" or str(request.rel_url).startswith("/plugins/load_main/") or str(request.rel_url).startswith("/static/") or str(request.rel_url).startswith("/locales/") or str(request.rel_url).startswith("/legacy/") or str(request.rel_url).startswith("/steam_resource/") or str(request.rel_url).startswith("/frontend/") or assets_regex.match(str(request.rel_url)) or frontend_regex.match(str(request.rel_url)):
if str(request.method) == "OPTIONS" or request.headers.get('Authentication') == csrf_token or str(request.rel_url) == "/auth/token" or str(request.rel_url).startswith("/plugins/load_main/") or str(request.rel_url).startswith("/static/") or str(request.rel_url).startswith("/legacy/") or str(request.rel_url).startswith("/steam_resource/") or str(request.rel_url).startswith("/frontend/") or assets_regex.match(str(request.rel_url)) or frontend_regex.match(str(request.rel_url)):
return await handler(request)
return Response(text='Forbidden', status='403')
+129
View File
@@ -0,0 +1,129 @@
{
"branch_select": {
"update_channel": {
"label": "Update Channel"
}
},
"reload": "Reload",
"uninstall": "Uninstall",
"Developer": {
"enabling": "Enabling",
"disabling": "Disabling",
"5secreload": "Reloading in 5 seconds"
},
"DeveloperIndex": {
"valve_internal": {
"label": "Enable Valve Internal",
"desc1": "Enables the Valve internal developer menu.",
"desc2": "Do not touch anything in this menu unless you know what it does."
},
"react_devtools": {
"label": "Enable React DevTools",
"desc": "Enables connection to a computer running React DevTools. Changing this setting will reload Steam. Set the IP address before enabling."
}
},
"PluginCard": {
"plugin_version_label": "Plugin Version",
"plugin_full_access": "This plugin has full access to your Steam Deck.",
"plugin_install": "Install",
"plugin_no_desc": "No description provided."
},
"PluginInstallModal": {
"install": {
"title": "Install {{artifact}}",
"desc": "Are you sure you want to install {{artifact}} {{version}}?",
"button_idle": "Install",
"button_processing": "Installing"
}
},
"PluginListIndex": {
"list_no_plugin": "No plugins installed!",
"list_update_to": "Update to {{name}}",
"list_plug_actions_label": "Plugin Actions"
},
"PluginLoader": {
"enabling": "Enabling",
"disabling": "Disabling",
"decky_update_available": "Update to {{tag_name}} available!",
"plugin_update_one": "Updates available for 1 plugin!",
"plugin_update_other": "Updates available for {{number}} plugins!",
"plugin_uninstall": {
"title": "Uninstall {{name}}",
"desc": "Are you sure you want to uninstall {{name}}?",
"button": "Uninstall"
},
"plugin_load": {
"plugin_load_error": "Error loading plugin {{name}}",
"plugin_load_error_toast": "Error loading {{name}}"
},
"error": "Error",
"plugin_error_uninstall": "Please go to {{-icon}} in the Decky menu if you need to uninstall this plugin.",
"file_picker_cancel_text": "User canceled"
},
"RemoteDebugging": {
"remote_cef": {
"label": "Allow Remote CEF Debugging",
"desc": "Allow unauthenticated access to the CEF debugger to anyone in your network"
}
},
"SettingsGeneralIndex": {
"developer_mode": {
"label": "Developer mode",
"desc": "Enables Decky's developer settings."
},
"manual_plugin": {
"label": "Manual plugin install",
"button": "Install"
}
},
"SettingsIndex": {
"general_title": "General",
"plugins_title": "Plugins",
"developer_title": "Developer",
"navbar_settings": "Decky Settings"
},
"Store": {
"store_tabs": {
"title": "Browse",
"about": "About",
"alph_desc": "Alphabetical (A to Z)",
"alph_asce": "Alphabetical (Z to A)"
},
"store_sort": {
"label": "Sort",
"label_def": "Last Updated (Newest)"
},
"store_filter": {
"label": "Filter",
"label_def": "All"
},
"store_search_label": "Search",
"store_testing_cta": "Please consider testing new plugins to help the Decky Loader team!",
"store_contrib": {
"label": "Contributing",
"desc": "If you would like to contribute to the Decky Plugin Store, check the SteamDeckHomebrew/decky-plugin-template repository on GitHub. Information on development and distribution is available in the README."
},
"store_source": {
"label": "Source Code",
"desc": "All plugin source code is available on SteamDeckHomebrew/decky-plugin-database repository on GitHub."
}
},
"StoreSelect": {
"store_channel_label": "Store Channel",
"custom_store_label": "Custom Store"
},
"Updater": {
"no_patch_notes_desc": "no patch notes for this version",
"decky_updates": "Decky Updates",
"updates": {
"label": "Updates",
"cur_version": "Current version: {{ver}}",
"lat_version": "Latest version: {{ver}}",
"checking": "'Checking",
"check_button": "Check For Updates",
"install_button": "Install Update",
"reloading": "Reloading",
"updating": "Updating"
}
}
}
-5
View File
@@ -1,5 +0,0 @@
{
"update_channel":{
"label": "Update Channel"
}
}
-4
View File
@@ -1,4 +0,0 @@
{
"reload": "Reload",
"uninstall": "Uninstall"
}
-11
View File
@@ -1,11 +0,0 @@
{
"valve_internal":{
"label": "Enable Valve Internal",
"desc1": "Enables the Valve internal developer menu.",
"desc2": "Do not touch anything in this menu unless you know what it does."
},
"react_devtools":{
"label": "Enable React DevTools",
"desc": "Enables connection to a computer running React DevTools. Changing this setting will reload Steam. Set the IP address before enabling."
}
}
-6
View File
@@ -1,6 +0,0 @@
{
"plugin_version_label": "Plugin Version",
"plugin_full_access": "This plugin has full access to your Steam Deck.",
"plugin_install": "Install",
"plugin_no_desc": "No description provided."
}
@@ -1,8 +0,0 @@
{
"install":{
"title": "Install {{artifact}}",
"desc": "Are you sure you want to install {{artifact}} {{version}}?",
"button_idle": "Install",
"button_processing": "Installing"
}
}
-5
View File
@@ -1,5 +0,0 @@
{
"list_no_plugin": "No plugins installed!",
"list_update_to": "Update to {{name}}",
"list_plug_actions_label": "Plugin Actions"
}
-6
View File
@@ -1,6 +0,0 @@
{
"remote_cef":{
"label": "Allow Remote CEF Debugging",
"desc": "Allow unauthenticated access to the CEF debugger to anyone in your network"
}
}
@@ -1,10 +0,0 @@
{
"developer_mode":{
"label": "Developer mode",
"desc": "Enables Decky's developer settings."
},
"manual_plugin":{
"label": "Manual plugin install",
"button": "Install"
}
}
-6
View File
@@ -1,6 +0,0 @@
{
"general_title": "General",
"plugins_title": "Plugins",
"developer_title": "Developer",
"navbar_settings": "Decky Settings"
}
-28
View File
@@ -1,28 +0,0 @@
{
"store_tabs":{
"title": "Browse",
"about": "About",
"alph_desc": "Alphabetical (A to Z)",
"alph_asce": "Alphabetical (Z to A)"
},
"store_sort":{
"label": "Sort",
"label_def": "Last Updated (Newest)"
},
"store_filter":{
"label": "Filter",
"label_def": "All"
},
"store_search_label": "Search",
"store_testing_cta": "Please consider testing new plugins to help the Decky Loader team!",
"store_contrib":{
"label": "Contributing",
"desc": "If you would like to contribute to the Decky Plugin Store, check the SteamDeckHomebrew/decky-plugin-template repository on GitHub. Information on development and distribution is available in the README."
},
"store_source":{
"label": "Source Code",
"desc": "All plugin source code is available on SteamDeckHomebrew/decky-plugin-database repository on GitHub."
}
}
-4
View File
@@ -1,4 +0,0 @@
{
"store_channel_label": "Store Channel",
"custom_store_label": "Custom Store"
}
-15
View File
@@ -1,15 +0,0 @@
{
"no_patch_notes_desc": "no patch notes for this version",
"decky_updates": "Decky Updates",
"updates":{
"label": "Updates",
"cur_version": "Current version: {{ver}}",
"lat_version": "Latest version: {{ver}}",
"checking": "'Checking",
"check_button": "Check For Updates",
"install_button": "Install Update",
"reloading": "Reloading",
"updating": "Updating"
}
}
-15
View File
@@ -1,15 +0,0 @@
{
"enabling": "Enabling",
"disabling": "Disabling",
"decky_update_available": "Update to {{tag_name}} available!",
"plugin_update_one": "Updates available for 1 plugin!",
"plugin_update_other": "Updates available for {{number}} plugins!",
"plugin_uninstall_title":"Uninstall {{name}}",
"plugin_uninstall_desc": "Are you sure you want to uninstall {{name}}?",
"plugin_uninstall_button": "Uninstall",
"plugin_load_error": "Error loading plugin {{name}}",
"plugin_load_error_toast": "Error loading {{name}}",
"error": "Error",
"plugin_error_uninstall": "Please go to {{-icon}} in the Decky menu if you need to uninstall this plugin.",
"file_picker_cancel_text": "User canceled"
}
+127
View File
@@ -0,0 +1,127 @@
{
"update_channel": {
"label": "Canale di aggiornamento"
},
"reload": "Ricarica",
"uninstall": "Rimuovi",
"Developer": {
"enabling": "Abilitando",
"disabling": "Disabilitando",
"5secreload": "Ricaricando in 5 secondi"
},
"DeveloperIndex": {
"valve_internal": {
"label": "Abilita Menu Sviluppatore",
"desc1": "Abilita il menu di sviluppo interno di Valve.",
"desc2": "Non toccare nulla in questo menu se non sai quello che fa."
},
"react_devtools": {
"label": "Abilita i DevTools di React",
"desc": "Abilita la connessione ad un computer che esegue i DevTools di React. Cambiando questa impostazione ricaricherà Steam. Imposta l'indirizzo IP prima di abilitarlo."
}
},
"PluginCard": {
"plugin_version_label": "Versione Plugin",
"plugin_full_access": "Questo pluugin ha accesso completo al tuo Steam Deck.",
"plugin_install": "Installa",
"plugin_no_desc": "Nessuna descrizione fornita."
},
"PluginInstallModal": {
"install": {
"title": "Installa {{artifact}}",
"desc": "Sei sicuro di voler installare {{artifact}} {{version}}?",
"button_idle": "Installa",
"button_processing": "Installando"
}
},
"PluginListIndex": {
"list_no_plugin": "Nessun plugin installato!",
"list_update_to": "Aggiornamento a {{name}}",
"list_plug_actions_label": "Operazioni sui plugins"
},
"PluginLoader": {
"enabling": "Abilitando",
"disabling": "Disabilitando",
"decky_update_available": "Disponibile aggiornamento a {{tag_name}}!",
"plugin_update_one": "Aggiornamento disponibile per un plugin!",
"plugin_update_other": "Aggiornamento disponibile per {{number}} plugins!",
"plugin_uninstall": {
"title": "Rimozione di {{name}}",
"desc": "Rimuovo {{name}}?",
"button": "Rimuovi"
},
"plugin_load_error": {
"message": "Errore caricando il plugin {{name}}",
"toast": "Errore caricando {{name}}"
},
"error": "Errore",
"plugin_error_uninstall": "Per rimuovere questo plugin vai su {{-icon}} nel menu di Decky.",
"file_picker_cancel_text": "Annullato dall'utente"
},
"RemoteDebugging": {
"remote_cef": {
"label": "Permetti il debug remoto di CEF",
"desc": "Permetti l'accesso non autenticato a chiunque sulla tua rete locale al debugger di CEF."
}
},
"SettingsGeneralIndex": {
"developer_mode": {
"label": "Modalità sviluppatore",
"desc": "Abilità le impostazioni di sviluppo di Decky."
},
"manual_plugin": {
"label": "Installazione manuale plugins",
"button": "Installa"
}
},
"SettingsIndex": {
"general_title": "Generali",
"plugins_title": "Plugins",
"developer_title": "Sviluppatore",
"navbar_settings": "Impostazioni Decky"
},
"Store": {
"store_tabs": {
"title": "Naviga",
"about": "About",
"alph_desc": "Alfabetico (A a Z)",
"alph_asce": "Alfabetico (Z a A)"
},
"store_sort": {
"label": "Ordina",
"label_def": "Ultimo aggiornato (Più recente)"
},
"store_filter": {
"label": "Filtra",
"label_def": "Tutto"
},
"store_search_label": "Cerca",
"store_testing_cta": "Valuta la possibilità di testare nuovi plugin per aiutare il team di Decky Loader!",
"store_contrib": {
"label": "Contribuisci",
"desc": "Se desideri contribuire allo store di Decky, puoi trovare un template caricato su GitHub all'indirizzo SteamDeckHomebrew/decky-plugin-template. Informazioni riguardo sviluppo e distribuzione sono disponibili nel README."
},
"store_source": {
"label": "Codice Sorgente",
"desc": "Tutto il codice sorgente dei plugin è disponibile su GitHub all'indirizzo SteamDeckHomebrew/decky-plugin-database"
}
},
"StoreSelect": {
"store_channel_label": "Canale del negozio",
"custom_store_label": "Negozio custom"
},
"Updater": {
"no_patch_notes_desc": "nessuna patch notes per questa versione",
"decky_updates": "Aggiornamenti di Decky",
"updates": {
"label": "Aggiornamenti",
"cur_version": "Versione attuale: {{ver}}",
"lat_version": "Ultima versione: {{ver}}",
"checking": "Controllando",
"check_button": "Cerca aggiornamenti",
"install_button": "Installa aggiornamento",
"reloading": "Ricaricando",
"updating": "Aggiornando"
}
}
}
-5
View File
@@ -1,5 +0,0 @@
{
"update_channel":{
"label": "Canale di aggiornamento"
}
}
-4
View File
@@ -1,4 +0,0 @@
{
"reload": "Ricarica",
"uninstall": "Rimuovi"
}
-11
View File
@@ -1,11 +0,0 @@
{
"valve_internal":{
"label": "Abilita Menu Sviluppatore",
"desc1": "Abilita il menu interno di sviluppo di Valve.",
"desc2": "Non toccare nulla in questo menu se non sai quello che fa."
},
"react_devtools":{
"label": "Abilita i DevTools di React",
"desc": "Abilita la connessione ad un computer che esegue i DevTools di React. Cambiando questa impostazione ricaricherà Steam. Imposta l'indirizzo IP prima di abilitarlo."
}
}
-6
View File
@@ -1,6 +0,0 @@
{
"plugin_version_label": "Versione Plugin",
"plugin_full_access": "Questo pluugin ha accesso completo al tuo Steam Deck.",
"plugin_install": "Installa",
"plugin_no_desc": "Nessuna descrizione fornita."
}
@@ -1,8 +0,0 @@
{
"install":{
"title": "Installa {{artifact}}",
"desc": "Sei sicuro di voler installare {{artifact}} {{version}}?",
"button_idle": "Installa",
"button_processing": "Installando"
}
}
-5
View File
@@ -1,5 +0,0 @@
{
"list_no_plugin": "Nessun plugin installato!",
"list_update_to": "Aggiornamento a {{name}}",
"list_plug_actions_label": "Operazioni sui plugins"
}
-6
View File
@@ -1,6 +0,0 @@
{
"remote_cef":{
"label": "Permetti il debug remoto di CEF",
"desc": "Permetti l'accesso non autenticato a chiunque sulla tua rete locale al debugger di CEF."
}
}
@@ -1,10 +0,0 @@
{
"developer_mode":{
"label": "Modalità sviluppatore",
"desc": "Abilità le impostazioni di sviluppo di Decky."
},
"manual_plugin":{
"label": "Installazione manuale plugins",
"button": "Installa"
}
}
-6
View File
@@ -1,6 +0,0 @@
{
"general_title": "Generali",
"plugins_title": "Plugins",
"developer_title": "Sviluppatore",
"navbar_settings": "Impostazioni Decky"
}
-29
View File
@@ -1,29 +0,0 @@
{
"store_tabs":{
"title": "Naviga",
"about": "About",
"alph_desc": "Alfabetico (A a Z)",
"alph_asce": "Alfabetico (Z a A)"
},
"store_sort":{
"label": "Ordina",
"label_def": "Ultimo aggiornato (Più recente)"
},
"store_filter":{
"label": "Filtra",
"label_def": "Tutto"
},
"store_search_label": "Cerca",
"store_testing_cta": "Valuta la possibilità di testare nuovi plugin per aiutare il team di Decky Loader!",
"store_contrib":{
"label": "Contribuisci",
"desc": "Se desideri contribuire allo store di Decky, puoi trovare un template caricato su GitHub all'indirizzo SteamDeckHomebrew/decky-plugin-template. Informazioni riguardo sviluppo e distribuzione sono disponibili nel README."
},
"store_source":{
"label": "Codice Sorgente",
"desc": "Tutto il codice sorgente dei plugin è disponibile su GitHub all'indirizzo SteamDeckHomebrew/decky-plugin-database"
}
}
-4
View File
@@ -1,4 +0,0 @@
{
"store_channel_label": "Canale del negozio",
"custom_store_label": "Negozio custom"
}
-15
View File
@@ -1,15 +0,0 @@
{
"no_patch_notes_desc": "nessuna patch notes per questa versione",
"decky_updates": "Aggiornamenti di Decky",
"updates":{
"label": "Aggiornamenti",
"cur_version": "Versione attuale: {{ver}}",
"lat_version": "Ultima versione: {{ver}}",
"checking": "Controllando",
"check_button": "Cerca aggiornamenti",
"install_button": "Installa aggiornamento",
"reloading": "Ricaricando",
"updating": "Aggiornando"
}
}
-15
View File
@@ -1,15 +0,0 @@
{
"enabling": "Abilitando",
"disabling": "Disabilitando",
"decky_update_available": "Disponibile aggiornamento a {{tag_name}}!",
"plugin_update_one": "Aggiornamento disponibile per un plugin!",
"plugin_update_other": "Aggiornamento disponibile per {{number}} plugins!",
"plugin_uninstall_title":"Rimozione di {{name}}",
"plugin_uninstall_desc": "Rimuovo {{name}}?",
"plugin_uninstall_button": "Rimuovi",
"plugin_load_error": "Errore caricando il plugin {{name}}",
"plugin_load_error_toast": "Errore caricando {{name}}",
"error": "Errore",
"plugin_error_uninstall": "Per rimuovere questo plugin vai su {{-icon}} nel menu di Decky.",
"file_picker_cancel_text": "Annullato dall'utente"
}
+2
View File
@@ -22,6 +22,7 @@
"@types/react-router": "5.1.18",
"@types/webpack": "^5.28.0",
"husky": "^8.0.1",
"eslint": "^8.33.0",
"import-sort-style-module": "^6.0.0",
"inquirer": "^8.2.4",
"prettier": "^2.7.1",
@@ -30,6 +31,7 @@
"react-dom": "16.14.0",
"rollup": "^2.76.0",
"rollup-plugin-delete": "^2.0.0",
"eslint-plugin-react-hooks": "^4.6.0",
"rollup-plugin-external-globals": "^0.6.1",
"rollup-plugin-polyfill-node": "^0.10.2",
"tslib": "^2.4.0",
+405 -2
View File
@@ -12,6 +12,8 @@ specifiers:
'@types/react-router': 5.1.18
'@types/webpack': ^5.28.0
decky-frontend-lib: ^3.18.10
eslint: ^8.33.0
eslint-plugin-react-hooks: ^4.6.0
husky: ^8.0.1
i18next: ^22.4.9
i18next-browser-languagedetector: ^7.0.1
@@ -56,6 +58,8 @@ devDependencies:
'@types/react-file-icon': 1.0.1
'@types/react-router': 5.1.18
'@types/webpack': 5.28.0
eslint: 8.33.0
eslint-plugin-react-hooks: 4.6.0_eslint@8.33.0
husky: 8.0.1
import-sort-style-module: 6.0.0
inquirer: 8.2.4
@@ -281,6 +285,43 @@ packages:
to-fast-properties: 2.0.0
dev: true
/@eslint/eslintrc/1.4.1:
resolution: {integrity: sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
ajv: 6.12.6
debug: 4.3.4
espree: 9.4.1
globals: 13.20.0
ignore: 5.2.0
import-fresh: 3.3.0
js-yaml: 4.1.0
minimatch: 3.1.2
strip-json-comments: 3.1.1
transitivePeerDependencies:
- supports-color
dev: true
/@humanwhocodes/config-array/0.11.8:
resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==}
engines: {node: '>=10.10.0'}
dependencies:
'@humanwhocodes/object-schema': 1.2.1
debug: 4.3.4
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
dev: true
/@humanwhocodes/module-importer/1.0.1:
resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
engines: {node: '>=12.22'}
dev: true
/@humanwhocodes/object-schema/1.2.1:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
dev: true
/@jridgewell/gen-mapping/0.1.1:
resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==}
engines: {node: '>=6.0.0'}
@@ -717,12 +758,26 @@ packages:
acorn: 8.7.1
dev: true
/acorn-jsx/5.3.2_acorn@8.8.2:
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
peerDependencies:
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
dependencies:
acorn: 8.8.2
dev: true
/acorn/8.7.1:
resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
/acorn/8.8.2:
resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
/aggregate-error/3.1.0:
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
engines: {node: '>=8'}
@@ -780,6 +835,10 @@ packages:
sprintf-js: 1.0.3
dev: true
/argparse/2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true
/array-union/2.1.0:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
@@ -865,6 +924,11 @@ packages:
engines: {node: '>=4'}
dev: true
/callsites/3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
dev: true
/caniuse-lite/1.0.30001366:
resolution: {integrity: sha512-yy7XLWCubDobokgzudpkKux8e0UOOnLHE6mlNJBzT3lZJz6s5atSEzjoL+fsCPkI0G8MP5uVdDx1ur/fXEWkZA==}
dev: true
@@ -964,7 +1028,7 @@ packages:
dev: true
/concat-map/0.0.1:
resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=}
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
/convert-source-map/1.8.0:
@@ -991,6 +1055,15 @@ packages:
- encoding
dev: false
/cross-spawn/7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
dependencies:
path-key: 3.1.1
shebang-command: 2.0.0
which: 2.0.2
dev: true
/csstype/3.1.0:
resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==}
@@ -1015,6 +1088,10 @@ packages:
character-entities: 2.0.2
dev: false
/deep-is/0.1.4:
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
dev: true
/deepmerge/4.2.2:
resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==}
engines: {node: '>=0.10.0'}
@@ -1062,6 +1139,13 @@ packages:
path-type: 4.0.0
dev: true
/doctrine/3.0.0:
resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==}
engines: {node: '>=6.0.0'}
dependencies:
esutils: 2.0.3
dev: true
/electron-to-chromium/1.4.189:
resolution: {integrity: sha512-dQ6Zn4ll2NofGtxPXaDfY2laIa6NyCQdqXYHdwH90GJQW0LpJJib0ZU/ERtbb0XkBEmUD2eJtagbOie3pdMiPg==}
dev: true
@@ -1098,11 +1182,25 @@ packages:
engines: {node: '>=0.8.0'}
dev: true
/escape-string-regexp/4.0.0:
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
engines: {node: '>=10'}
dev: true
/escape-string-regexp/5.0.0:
resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
engines: {node: '>=12'}
dev: false
/eslint-plugin-react-hooks/4.6.0_eslint@8.33.0:
resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==}
engines: {node: '>=10'}
peerDependencies:
eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0
dependencies:
eslint: 8.33.0
dev: true
/eslint-scope/5.1.1:
resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
engines: {node: '>=8.0.0'}
@@ -1111,12 +1209,104 @@ packages:
estraverse: 4.3.0
dev: true
/eslint-scope/7.1.1:
resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
esrecurse: 4.3.0
estraverse: 5.3.0
dev: true
/eslint-utils/3.0.0_eslint@8.33.0:
resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==}
engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0}
peerDependencies:
eslint: '>=5'
dependencies:
eslint: 8.33.0
eslint-visitor-keys: 2.1.0
dev: true
/eslint-visitor-keys/2.1.0:
resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==}
engines: {node: '>=10'}
dev: true
/eslint-visitor-keys/3.3.0:
resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dev: true
/eslint/8.33.0:
resolution: {integrity: sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
hasBin: true
dependencies:
'@eslint/eslintrc': 1.4.1
'@humanwhocodes/config-array': 0.11.8
'@humanwhocodes/module-importer': 1.0.1
'@nodelib/fs.walk': 1.2.8
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.1.1
eslint-utils: 3.0.0_eslint@8.33.0
eslint-visitor-keys: 3.3.0
espree: 9.4.1
esquery: 1.4.0
esutils: 2.0.3
fast-deep-equal: 3.1.3
file-entry-cache: 6.0.1
find-up: 5.0.0
glob-parent: 6.0.2
globals: 13.20.0
grapheme-splitter: 1.0.4
ignore: 5.2.0
import-fresh: 3.3.0
imurmurhash: 0.1.4
is-glob: 4.0.3
is-path-inside: 3.0.3
js-sdsl: 4.3.0
js-yaml: 4.1.0
json-stable-stringify-without-jsonify: 1.0.1
levn: 0.4.1
lodash.merge: 4.6.2
minimatch: 3.1.2
natural-compare: 1.4.0
optionator: 0.9.1
regexpp: 3.2.0
strip-ansi: 6.0.1
strip-json-comments: 3.1.1
text-table: 0.2.0
transitivePeerDependencies:
- supports-color
dev: true
/espree/9.4.1:
resolution: {integrity: sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
acorn: 8.8.2
acorn-jsx: 5.3.2_acorn@8.8.2
eslint-visitor-keys: 3.3.0
dev: true
/esprima/4.0.1:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
hasBin: true
dev: true
/esquery/1.4.0:
resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==}
engines: {node: '>=0.10'}
dependencies:
estraverse: 5.3.0
dev: true
/esrecurse/4.3.0:
resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==}
engines: {node: '>=4.0'}
@@ -1142,6 +1332,11 @@ packages:
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
dev: true
/esutils/2.0.3:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'}
dev: true
/events/3.3.0:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
@@ -1179,6 +1374,10 @@ packages:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
dev: true
/fast-levenshtein/2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
dev: true
/fastq/1.13.0:
resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
dependencies:
@@ -1192,6 +1391,13 @@ packages:
escape-string-regexp: 1.0.5
dev: true
/file-entry-cache/6.0.1:
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
engines: {node: ^10.12.0 || >=12.0.0}
dependencies:
flat-cache: 3.0.4
dev: true
/fill-range/7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
@@ -1207,6 +1413,26 @@ packages:
resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==}
dev: true
/find-up/5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
dependencies:
locate-path: 6.0.0
path-exists: 4.0.0
dev: true
/flat-cache/3.0.4:
resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==}
engines: {node: ^10.12.0 || >=12.0.0}
dependencies:
flatted: 3.2.7
rimraf: 3.0.2
dev: true
/flatted/3.2.7:
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
dev: true
/fs.realpath/1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true
@@ -1235,6 +1461,13 @@ packages:
is-glob: 4.0.3
dev: true
/glob-parent/6.0.2:
resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
engines: {node: '>=10.13.0'}
dependencies:
is-glob: 4.0.3
dev: true
/glob-to-regexp/0.4.1:
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
dev: true
@@ -1255,6 +1488,13 @@ packages:
engines: {node: '>=4'}
dev: true
/globals/13.20.0:
resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==}
engines: {node: '>=8'}
dependencies:
type-fest: 0.20.2
dev: true
/globby/10.0.2:
resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==}
engines: {node: '>=8'}
@@ -1273,6 +1513,10 @@ packages:
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
dev: true
/grapheme-splitter/1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
dev: true
/has-flag/3.0.0:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
@@ -1350,6 +1594,14 @@ packages:
resolve-from: 3.0.0
dev: true
/import-fresh/3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
dependencies:
parent-module: 1.0.1
resolve-from: 4.0.0
dev: true
/import-sort-config/6.0.0:
resolution: {integrity: sha512-FJpF2F3+30JXqH1rJKeajxoSCHCueai3/0ntDN4y3GJL5pjnLDt/VjCy5FzjH7u0NHnllL/zVEf1wfmsVxJlPQ==}
dependencies:
@@ -1399,6 +1651,11 @@ packages:
resolve: 1.22.1
dev: true
/imurmurhash/0.1.4:
resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
engines: {node: '>=0.8.19'}
dev: true
/indent-string/4.0.0:
resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
engines: {node: '>=8'}
@@ -1524,6 +1781,10 @@ packages:
engines: {node: '>=10'}
dev: true
/isexe/2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true
/jest-worker/27.5.1:
resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
engines: {node: '>= 10.13.0'}
@@ -1533,6 +1794,10 @@ packages:
supports-color: 8.1.1
dev: true
/js-sdsl/4.3.0:
resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==}
dev: true
/js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -1544,6 +1809,13 @@ packages:
esprima: 4.0.1
dev: true
/js-yaml/4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
dependencies:
argparse: 2.0.1
dev: true
/jsesc/2.5.2:
resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
engines: {node: '>=4'}
@@ -1562,6 +1834,10 @@ packages:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
dev: true
/json-stable-stringify-without-jsonify/1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
dev: true
/json5/2.2.1:
resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==}
engines: {node: '>=6'}
@@ -1573,11 +1849,30 @@ packages:
engines: {node: '>=6'}
dev: false
/levn/0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
dependencies:
prelude-ls: 1.2.1
type-check: 0.4.0
dev: true
/loader-runner/4.3.0:
resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==}
engines: {node: '>=6.11.5'}
dev: true
/locate-path/6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
dependencies:
p-locate: 5.0.0
dev: true
/lodash.merge/4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
/lodash.uniqueid/4.0.1:
resolution: {integrity: sha512-GQQWaIeGlL6DIIr06kj1j6sSmBxyNMwI8kaX9aKpHR/XsMTiaXDVPNPAkiboOTK9OJpTJF/dXT3xYoFQnj386Q==}
dev: false
@@ -2046,6 +2341,10 @@ packages:
resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==}
dev: true
/natural-compare/1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true
/neo-async/2.6.2:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
dev: true
@@ -2083,6 +2382,18 @@ packages:
mimic-fn: 2.1.0
dev: true
/optionator/0.9.1:
resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==}
engines: {node: '>= 0.8.0'}
dependencies:
deep-is: 0.1.4
fast-levenshtein: 2.0.6
levn: 0.4.1
prelude-ls: 1.2.1
type-check: 0.4.0
word-wrap: 1.2.3
dev: true
/ora/5.4.1:
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
engines: {node: '>=10'}
@@ -2103,6 +2414,20 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/p-limit/3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
dependencies:
yocto-queue: 0.1.0
dev: true
/p-locate/5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
dependencies:
p-limit: 3.1.0
dev: true
/p-map/3.0.0:
resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==}
engines: {node: '>=8'}
@@ -2110,6 +2435,13 @@ packages:
aggregate-error: 3.1.0
dev: true
/parent-module/1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
dependencies:
callsites: 3.1.0
dev: true
/parse-json/4.0.0:
resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==}
engines: {node: '>=4'}
@@ -2118,11 +2450,21 @@ packages:
json-parse-better-errors: 1.0.2
dev: true
/path-exists/4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
dev: true
/path-is-absolute/1.0.1:
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
engines: {node: '>=0.10.0'}
dev: true
/path-key/3.1.1:
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
engines: {node: '>=8'}
dev: true
/path-parse/1.0.7:
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
dev: true
@@ -2141,6 +2483,11 @@ packages:
engines: {node: '>=8.6'}
dev: true
/prelude-ls/1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
dev: true
/prettier-plugin-import-sort/0.0.7_prettier@2.7.1:
resolution: {integrity: sha512-O0KlUSq+lwvh+UiN3wZDT6wWkf7TNxTVv2/XXE5KqpRNbFJq3nRg2ftzBYFFO8QGpdWIrOB0uCTCtFjIxmVKQw==}
peerDependencies:
@@ -2294,6 +2641,11 @@ packages:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
dev: false
/regexpp/3.2.0:
resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==}
engines: {node: '>=8'}
dev: true
/remark-gfm/3.0.1:
resolution: {integrity: sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==}
dependencies:
@@ -2461,6 +2813,18 @@ packages:
randombytes: 2.1.0
dev: true
/shebang-command/2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
dependencies:
shebang-regex: 3.0.0
dev: true
/shebang-regex/3.0.0:
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
engines: {node: '>=8'}
dev: true
/signal-exit/3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
dev: true
@@ -2516,6 +2880,11 @@ packages:
ansi-regex: 5.0.1
dev: true
/strip-json-comments/3.1.1:
resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
engines: {node: '>=8'}
dev: true
/style-to-object/0.3.0:
resolution: {integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==}
dependencies:
@@ -2583,11 +2952,15 @@ packages:
hasBin: true
dependencies:
'@jridgewell/source-map': 0.3.2
acorn: 8.7.1
acorn: 8.8.2
commander: 2.20.3
source-map-support: 0.5.21
dev: true
/text-table/0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true
/through/2.3.8:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
dev: true
@@ -2631,6 +3004,18 @@ packages:
resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
dev: true
/type-check/0.4.0:
resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==}
engines: {node: '>= 0.8.0'}
dependencies:
prelude-ls: 1.2.1
dev: true
/type-fest/0.20.2:
resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==}
engines: {node: '>=10'}
dev: true
/type-fest/0.21.3:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}
@@ -2824,6 +3209,19 @@ packages:
webidl-conversions: 3.0.1
dev: false
/which/2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
hasBin: true
dependencies:
isexe: 2.0.0
dev: true
/word-wrap/1.2.3:
resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
engines: {node: '>=0.10.0'}
dev: true
/wrap-ansi/7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
@@ -2837,6 +3235,11 @@ packages:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: true
/yocto-queue/0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: true
/zwitch/2.0.2:
resolution: {integrity: sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA==}
dev: false
+5 -2
View File
@@ -10,12 +10,15 @@ import externalGlobals from 'rollup-plugin-external-globals';
const hiddenWarnings = ['THIS_IS_UNDEFINED', 'EVAL'];
export default defineConfig({
input: 'src/index.tsx',
plugins: [
del({ targets: '../backend/static/*', force: true }),
commonjs(),
nodeResolve(),
commonjs({include: '../frontend/node_modules/**'}),
nodeResolve({
browser: true
}),
externalGlobals({
react: 'SP_REACT',
'react-dom': 'SP_REACTDOM',
@@ -2,8 +2,6 @@ import { ConfirmModal, Navigation, QuickAccessTab } from 'decky-frontend-lib';
import { FC, useState } from 'react';
import { useTranslation } from 'react-i18next';
const { t } = useTranslation('PluginInstallModal');
interface PluginInstallModalProps {
artifact: string;
version: string;
@@ -16,6 +14,7 @@ interface PluginInstallModalProps {
const PluginInstallModal: FC<PluginInstallModalProps> = ({ artifact, version, hash, onOK, onCancel, closeModal }) => {
const [loading, setLoading] = useState<boolean>(false);
const { t } = useTranslation();
return (
<ConfirmModal
bOKDisabled={loading}
@@ -29,13 +28,15 @@ const PluginInstallModal: FC<PluginInstallModalProps> = ({ artifact, version, ha
onCancel={async () => {
await onCancel();
}}
strTitle={t('install.title', artifact)}
strOKButtonText={loading ? t('install.button_processing') : t('install.button_idle')}
strTitle={t('PluginInstallModal.install.title', artifact)}
strOKButtonText={
loading ? t('PluginInstallModal.install.button_processing') : t('PluginInstallModal.install.button_idle')
}
>
{hash == 'False' ? (
<h3 style={{ color: 'red' }}>!!!!NO HASH PROVIDED!!!!</h3>
) : (
t('install.desc', artifact, version)
t('PluginInstallModal.install.desc', artifact, version)
)}
</ConfirmModal>
);
+5 -6
View File
@@ -9,19 +9,18 @@ import PluginList from './pages/plugin_list';
const DeveloperSettings = lazy(() => import('./pages/developer'));
const { t } = useTranslation('SettingsIndex');
export default function SettingsPage() {
const [isDeveloper, setIsDeveloper] = useSetting<boolean>('developer.enabled', false);
const { t } = useTranslation();
const pages = [
{
title: t('general_title'),
title: t('SettingsIndex.general_title'),
content: <GeneralSettings isDeveloper={isDeveloper} setIsDeveloper={setIsDeveloper} />,
route: '/decky/settings/general',
},
{
title: t('plugins_title'),
title: t('SettingsIndex.plugins_title'),
content: <PluginList />,
route: '/decky/settings/plugins',
},
@@ -29,7 +28,7 @@ export default function SettingsPage() {
if (isDeveloper)
pages.push({
title: t('developer_title'),
title: t('SettingsIndex.developer_title'),
content: (
<WithSuspense>
<DeveloperSettings />
@@ -38,5 +37,5 @@ export default function SettingsPage() {
route: '/decky/settings/developer',
});
return <SidebarNavigation title={t('settings_navbar') as string} showTitle pages={pages} />;
return <SidebarNavigation title={t('SettingsIndex.settings_navbar') as string} showTitle pages={pages} />;
}
@@ -7,7 +7,6 @@ import { callUpdaterMethod } from '../../../../updater';
import { useSetting } from '../../../../utils/hooks/useSetting';
const logger = new Logger('BranchSelect');
const { t } = useTranslation('BranchSelect');
enum UpdateBranch {
Stable,
@@ -16,12 +15,13 @@ enum UpdateBranch {
}
const BranchSelect: FunctionComponent<{}> = () => {
const { t } = useTranslation();
const [selectedBranch, setSelectedBranch] = useSetting<UpdateBranch>('branch', UpdateBranch.Prerelease);
return (
// Returns numerical values from 0 to 2 (with current branch setup as of 8/28/22)
// 0 being stable, 1 being pre-release and 2 being nightly
<Field label={t('update_channel.label')}>
<Field label={t('BranchSelect.update_channel.label')}>
<Dropdown
rgOptions={Object.values(UpdateBranch)
.filter((branch) => typeof branch == 'string')
@@ -6,12 +6,12 @@ import { useSetting } from '../../../../utils/hooks/useSetting';
export default function RemoteDebuggingSettings() {
const [allowRemoteDebugging, setAllowRemoteDebugging] = useSetting<boolean>('cef_forward', false);
const { t } = useTranslation('RemoteDebugging');
const { t } = useTranslation();
return (
<Field
label={t('remote_cef.label')}
description={<span style={{ whiteSpace: 'pre-line' }}>{t('remote_cef.desc')}</span>}
label={t('RemoteDebugging.remote_cef.label')}
description={<span style={{ whiteSpace: 'pre-line' }}>{t('RemoteDebugging.remote_cef.desc')}</span>}
icon={<FaBug style={{ display: 'block' }} />}
>
<Toggle
@@ -8,17 +8,17 @@ import { Store } from '../../../../store';
import { useSetting } from '../../../../utils/hooks/useSetting';
const logger = new Logger('StoreSelect');
const { t } = useTranslation('StoreSelect');
const StoreSelect: FunctionComponent<{}> = () => {
const [selectedStore, setSelectedStore] = useSetting<Store>('store', Store.Default);
const [selectedStoreURL, setSelectedStoreURL] = useSetting<string | null>('store-url', null);
const { t } = useTranslation();
// Returns numerical values from 0 to 2 (with current branch setup as of 8/28/22)
// 0 being Default, 1 being Testing and 2 being Custom
return (
<>
<Field label={t('store_channel_label')}>
<Field label={t('StoreSelect.store_channel_label')}>
<Dropdown
rgOptions={Object.values(Store)
.filter((store) => typeof store == 'string')
@@ -35,7 +35,7 @@ const StoreSelect: FunctionComponent<{}> = () => {
</Field>
{selectedStore == Store.Custom && (
<Field
label={t('custom_store_label')}
label={t('StoreSelect.custom_store_label')}
indentLevel={1}
description={
<TextField
@@ -21,10 +21,10 @@ import InlinePatchNotes from '../../../patchnotes/InlinePatchNotes';
import WithSuspense from '../../../WithSuspense';
const MarkdownRenderer = lazy(() => import('../../../Markdown'));
const { t } = useTranslation('Updater');
function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | null; closeModal?: () => {} }) {
const SP = findSP();
const { t } = useTranslation();
return (
<Focusable onCancelButton={closeModal}>
<FocusRing>
@@ -47,7 +47,7 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n
<MarkdownRenderer onDismiss={closeModal}>{versionInfo.all[id].body}</MarkdownRenderer>
</WithSuspense>
) : (
t('no_patch_notes_desc')
t('Updater.no_patch_notes_desc')
)}
</div>
</Focusable>
@@ -60,7 +60,7 @@ function PatchNotesModal({ versionInfo, closeModal }: { versionInfo: VerInfo | n
initialColumn={0}
autoFocus={true}
fnGetColumnWidth={() => SP.innerWidth}
name={t('decky_updates') as string}
name={t('Updater.decky_updates') as string}
/>
</FocusRing>
</Focusable>
@@ -74,6 +74,8 @@ export default function UpdaterSettings() {
const [updateProgress, setUpdateProgress] = useState<number>(-1);
const [reloading, setReloading] = useState<boolean>(false);
const { t } = useTranslation();
useEffect(() => {
window.DeckyUpdater = {
updateProgress: (i) => {
@@ -97,11 +99,13 @@ export default function UpdaterSettings() {
<Field
onOptionsActionDescription={versionInfo?.all ? 'Patch Notes' : undefined}
onOptionsButton={versionInfo?.all ? showPatchNotes : undefined}
label={t('updates.label')}
label={t('Updater.updates.label')}
description={
versionInfo && (
<span style={{ whiteSpace: 'pre-line' }}>{`${t('updates.cur_version', { ver: versionInfo.current })}\n${
versionInfo.updatable ? t('updates.lat_version', { ver: versionInfo.remote?.tag_name }) : ''
<span style={{ whiteSpace: 'pre-line' }}>{`${t('Updater.updates.cur_version', {
ver: versionInfo.current,
})}\n${
versionInfo.updatable ? t('Updater.updates.lat_version', { ver: versionInfo.remote?.tag_name }) : ''
}`}</span>
)
}
@@ -131,10 +135,10 @@ export default function UpdaterSettings() {
}
>
{checkingForUpdates
? t('updates.checking')
? t('Updater.updates.checking')
: !versionInfo?.remote || versionInfo?.remote?.tag_name == versionInfo?.current
? t('updates.check_button')
: t('updates.install_button')}
? t('Updater.updates.check_button')
: t('Updater.updates.install_button')}
</DialogButton>
) : (
<ProgressBarWithInfo
@@ -142,7 +146,7 @@ export default function UpdaterSettings() {
bottomSeparator="none"
nProgress={updateProgress}
indeterminate={reloading}
sOperationText={reloading ? t('updates.reloading') : t('updates.updating')}
sOperationText={reloading ? t('Updater.updates.reloading') : t('Updater.updates.updating')}
/>
)}
</Field>
@@ -17,7 +17,7 @@ export default function GeneralSettings({
setIsDeveloper: (val: boolean) => void;
}) {
const [pluginURL, setPluginURL] = useState('');
const { t } = useTranslation('SettingsGeneralIndex');
const { t } = useTranslation();
return (
<div>
@@ -26,8 +26,8 @@ export default function GeneralSettings({
<StoreSelect />
<RemoteDebuggingSettings />
<Field
label={t('developer_mode.label')}
description={<span style={{ whiteSpace: 'pre-line' }}>{t('developer_mode.desc')}</span>}
label={t('SettingsGeneralIndex.developer_mode.label')}
description={<span style={{ whiteSpace: 'pre-line' }}>{t('SettingsGeneralIndex.developer_mode.desc')}</span>}
icon={<FaTools style={{ display: 'block' }} />}
>
<Toggle
@@ -38,12 +38,12 @@ export default function GeneralSettings({
/>
</Field>
<Field
label={t('manual_plugin.label')}
label={t('SettingsGeneralIndex.manual_plugin.label')}
description={<TextField label={'URL'} value={pluginURL} onChange={(e) => setPluginURL(e?.target.value)} />}
icon={<FaShapes style={{ display: 'block' }} />}
>
<DialogButton disabled={pluginURL.length == 0} onClick={() => installFromURL(pluginURL)}>
{t('manual_plugin.button')}
{t('SettingsGeneralIndex.manual_plugin.button')}
</DialogButton>
</Field>
</div>
@@ -8,7 +8,7 @@ import { useDeckyState } from '../../../DeckyState';
export default function PluginList() {
const { plugins, updates } = useDeckyState();
const { t } = useTranslation('PluginListIndex');
const { t } = useTranslation();
useEffect(() => {
window.DeckyPluginLoader.checkPluginUpdates();
@@ -17,7 +17,7 @@ export default function PluginList() {
if (plugins.length === 0) {
return (
<div>
<p>{t('list_no_plugin')}</p>
<p>{t('PluginListIndex.list_no_plugin')}</p>
</div>
);
}
@@ -38,7 +38,7 @@ export default function PluginList() {
onClick={() => requestPluginInstall(name, update)}
>
<div style={{ display: 'flex', flexDirection: 'row' }}>
{t('list_update_to', update.name)}
{t('PluginListIndex.list_update_to', update.name)}
<FaDownload style={{ paddingLeft: '2rem' }} />
</div>
</DialogButton>
@@ -47,12 +47,12 @@ export default function PluginList() {
style={{ height: '40px', width: '40px', padding: '10px 12px', minWidth: '40px' }}
onClick={(e: MouseEvent) =>
showContextMenu(
<Menu label={t('list_plug_actions_label')}>
<Menu label={t('PluginListIndex.list_plug_actions_label')}>
<MenuItem onSelected={() => window.DeckyPluginLoader.importPlugin(name, version)}>
{t('reload')}
{t('PluginListIndex.reload')}
</MenuItem>
<MenuItem onSelected={() => window.DeckyPluginLoader.uninstallPlugin(name)}>
{t('uninstall')}
{t('PluginListIndex.uninstall')}
</MenuItem>
</Menu>,
e.currentTarget ?? window,
+6 -6
View File
@@ -15,12 +15,12 @@ interface PluginCardProps {
plugin: StorePlugin;
}
const { t } = useTranslation('PluginCard');
const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
const [selectedOption, setSelectedOption] = useState<number>(0);
const root: boolean = plugin.tags.some((tag) => tag === 'root');
const { t } = useTranslation();
return (
<div
className="deckyStoreCard"
@@ -100,7 +100,7 @@ const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
plugin.description
) : (
<span>
<i style={{ color: '#666' }}>{t('plugin_no_desc')}</i>
<i style={{ color: '#666' }}>{t('PluginCard.plugin_no_desc')}</i>
</span>
)}
</span>
@@ -112,7 +112,7 @@ const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
color: '#fee75c',
}}
>
<i>{t('plugin_full_access')}</i>{' '}
<i>{t('PluginCard.plugin_full_access')}</i>{' '}
<a
className="deckyStoreCardDescriptionRootLink"
href="https://deckbrew.xyz/root"
@@ -149,7 +149,7 @@ const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
layout="below"
onClick={() => requestPluginInstall(plugin.name, plugin.versions[selectedOption])}
>
<span className="deckyStoreCardInstallText">{t('plugin_install')}</span>
<span className="deckyStoreCardInstallText">{t('PluginCard.plugin_install')}</span>
</ButtonItem>
</div>
<div
@@ -166,7 +166,7 @@ const PluginCard: FC<PluginCardProps> = ({ plugin }) => {
label: version.name,
})) as SingleDropdownOption[]
}
menuLabel={t('plugin_version_label') as string}
menuLabel={t('PluginCard.plugin_version_label') as string}
selectedOption={selectedOption}
onChange={({ data }) => setSelectedOption(data)}
/>
+26 -22
View File
@@ -16,8 +16,6 @@ import Logger from '../../logger';
import { StorePlugin, getPluginList } from '../../store';
import PluginCard from './PluginCard';
const { t } = useTranslation('Store');
const logger = new Logger('FilePicker');
const StorePage: FC<{}> = () => {
@@ -28,6 +26,8 @@ const StorePage: FC<{}> = () => {
return false;
});
const { t } = useTranslation();
useEffect(() => {
(async () => {
const res = await getPluginList();
@@ -57,13 +57,13 @@ const StorePage: FC<{}> = () => {
}}
tabs={[
{
title: t('store_tabs_title'),
title: t('Store.store_tabs.title'),
content: <BrowseTab children={{ data: data }} />,
id: 'browse',
renderTabAddon: () => <span className={TabCount}>{data.length}</span>,
},
{
title: t('store_tabs.about'),
title: t('Store.store_tabs.about'),
content: <AboutTab />,
id: 'about',
},
@@ -76,10 +76,12 @@ const StorePage: FC<{}> = () => {
};
const BrowseTab: FC<{ children: { data: StorePlugin[] } }> = (data) => {
const { t } = useTranslation();
const sortOptions = useMemo(
(): DropdownOption[] => [
{ data: 1, label: t('store_tabs.alph_desc') },
{ data: 2, label: t('store_tabs.alph_asce') },
{ data: 1, label: t('Store.store_tabs.alph_desc') },
{ data: 2, label: t('Store.store_tabs.alph_asce') },
],
[],
);
@@ -108,11 +110,11 @@ const BrowseTab: FC<{ children: { data: StorePlugin[] } }> = (data) => {
width: '47.5%',
}}
>
<span className="DialogLabel">{t("store_sort.label")}</span>
<span className="DialogLabel">{t("Store.store_sort.label")}</span>
<Dropdown
menuLabel={t("store_sort.label") as string}
menuLabel={t("Store.store_sort.label") as string}
rgOptions={sortOptions}
strDefaultLabel={t("store_sort.label_def") as string}
strDefaultLabel={t("Store.store_sort.label_def") as string}
selectedOption={selectedSort}
onChange={(e) => setSort(e.data)}
/>
@@ -125,11 +127,11 @@ const BrowseTab: FC<{ children: { data: StorePlugin[] } }> = (data) => {
marginLeft: 'auto',
}}
>
<span className="DialogLabel">{t("store_filter.label")}</span>
<span className="DialogLabel">{t("Store.store_filter.label")}</span>
<Dropdown
menuLabel={t("store_filter.label")}
menuLabel={t("Store.store_filter.label")}
rgOptions={filterOptions}
strDefaultLabel={t("store_filter.label_def")}
strDefaultLabel={t("Store.store_filter.label_def")}
selectedOption={selectedFilter}
onChange={(e) => setFilter(e.data)}
/>
@@ -139,7 +141,7 @@ const BrowseTab: FC<{ children: { data: StorePlugin[] } }> = (data) => {
<div style={{ justifyContent: 'center', display: 'flex' }}>
<Focusable style={{ display: 'flex', alignItems: 'center', width: '96%' }}>
<div style={{ width: '100%' }}>
<TextField label={t("store_search.label")} value={searchFieldValue} onChange={(e) => setSearchValue(e.target.value)} />
<TextField label={t("Store.store_search.label")} value={searchFieldValue} onChange={(e) => setSearchValue(e.target.value)} />
</div>
</Focusable>
</div>
@@ -154,11 +156,11 @@ const BrowseTab: FC<{ children: { data: StorePlugin[] } }> = (data) => {
maxWidth: '100%',
}}
>
<span className="DialogLabel">{t('store_sort.label')}</span>
<span className="DialogLabel">{t('Store.store_sort.label')}</span>
<Dropdown
menuLabel={t('store_sort.label') as string}
menuLabel={t('Store.store_sort.label') as string}
rgOptions={sortOptions}
strDefaultLabel={t('store_sort.label_def') as string}
strDefaultLabel={t('Store.store_sort.label_def') as string}
selectedOption={selectedSort}
onChange={(e) => setSort(e.data)}
/>
@@ -169,7 +171,7 @@ const BrowseTab: FC<{ children: { data: StorePlugin[] } }> = (data) => {
<Focusable style={{ display: 'flex', alignItems: 'center', width: '96%' }}>
<div style={{ width: '100%' }}>
<TextField
label={t('store_search.label')}
label={t('Store.store_search.label')}
value={searchFieldValue}
onChange={(e) => setSearchValue(e.target.value)}
/>
@@ -199,6 +201,8 @@ const BrowseTab: FC<{ children: { data: StorePlugin[] } }> = (data) => {
};
const AboutTab: FC<{}> = () => {
const { t } = useTranslation();
return (
<div
style={{
@@ -223,7 +227,7 @@ const AboutTab: FC<{}> = () => {
/>
<span className="deckyStoreAboutHeader">Testing</span>
<span>
{t('store_testing_cta')}{' '}
{t('Store.store_testing_cta')}{' '}
<a
href="https://deckbrew.xyz/testing"
target="_blank"
@@ -234,10 +238,10 @@ const AboutTab: FC<{}> = () => {
deckbrew.xyz/testing
</a>
</span>
<span className="deckyStoreAboutHeader">{t('store_contrib.label')}</span>
<span>{t('store_contrib.desc')}</span>
<span className="deckyStoreAboutHeader">{t('store_source.label')}</span>
<span>{t('store_source.desc')}</span>
<span className="deckyStoreAboutHeader">{t('Store.store_contrib.label')}</span>
<span>{t('Store.store_contrib.desc')}</span>
<span className="deckyStoreAboutHeader">{t('Store.store_source.label')}</span>
<span>{t('Store.store_source.desc')}</span>
</div>
);
};
+5 -2
View File
@@ -18,6 +18,7 @@ import {
staticClasses,
updaterFieldClasses,
} from 'decky-frontend-lib';
import { useTranslation } from 'react-i18next';
import { FaReact } from 'react-icons/fa';
import Logger from './logger';
@@ -58,9 +59,11 @@ export async function setShowValveInternal(show: boolean) {
}
export async function setShouldConnectToReactDevTools(enable: boolean) {
const { t } = useTranslation();
window.DeckyPluginLoader.toaster.toast({
title: (enable ? 'Enabling' : 'Disabling') + ' React DevTools',
body: 'Reloading in 5 seconds',
title: (enable ? t('Developer.enabling') : t('Developer.disabling')) + ' React DevTools',
body: t('Developer.5secreload'),
icon: <FaReact />,
});
await sleep(5000);
+10 -2
View File
@@ -11,12 +11,20 @@ i18n
load: 'languageOnly',
debug: true,
fallbackLng: 'en',
lng: 'en',
lng: 'it',
interpolation: {
escapeValue: false,
},
backend: {
loadPath: 'http://127.0.0.1:1337/locales/{{lng}}/{{ns}}.json',
loadPath: 'http://127.0.0.1:1337/locales/{{lng}}.json',
requestOptions: {
// used for fetch
credentials: 'include',
cache: 'no-cache',
},
customHeaders: {
Authentication: window.deckyAuthToken,
},
},
});
+17 -11
View File
@@ -26,8 +26,6 @@ const SettingsPage = lazy(() => import('./components/settings'));
const FilePicker = lazy(() => import('./components/modals/filepicker'));
const { t } = useTranslation('plugin-loader');
declare global {
interface Window {}
}
@@ -103,10 +101,11 @@ class PluginLoader extends Logger {
public async notifyUpdates() {
const versionInfo = await this.updateVersion();
const { t } = useTranslation('PluginLoader');
if (versionInfo?.remote && versionInfo?.remote?.tag_name != versionInfo?.current) {
this.toaster.toast({
title: 'Decky',
body: t('decky_update_available', versionInfo?.remote?.tag_name),
body: t('PluginLoader.decky_update_available', versionInfo?.remote?.tag_name),
onClick: () => Router.Navigate('/decky/settings'),
});
this.deckyState.setHasLoaderUpdate(true);
@@ -123,11 +122,12 @@ class PluginLoader extends Logger {
public async notifyPluginUpdates() {
const updates = await this.checkPluginUpdates();
const { t } = useTranslation();
if (updates?.size > 0) {
this.toaster.toast({
title: 'Decky',
//body: `Updates available for ${updates.size} plugin${updates.size > 1 ? 's' : ''}!`,
body: t('plugin_update', updates.size.toString(10), { count: updates.size }),
body: t('PluginLoader.plugin_update', updates.size.toString(10), { count: updates.size }),
onClick: () => Router.Navigate('/decky/settings/plugins'),
});
}
@@ -146,6 +146,7 @@ class PluginLoader extends Logger {
}
public uninstallPlugin(name: string) {
const { t } = useTranslation();
showModal(
<ConfirmModal
onOK={async () => {
@@ -154,10 +155,10 @@ class PluginLoader extends Logger {
onCancel={() => {
// do nothing
}}
strTitle={t('plugin_uninstall_title', name)}
strOKButtonText={t('plugin_uninstall_button')}
strTitle={t('PluginLoader.plugin_uninstall.title', name)}
strOKButtonText={t('PluginLoader.plugin_uninstall.button')}
>
{t('plugin_uninstall_desc', name)}
{t('PluginLoader.plugin_uninstall.desc', name)}
</ConfirmModal>,
);
}
@@ -233,6 +234,9 @@ class PluginLoader extends Logger {
Authentication: window.deckyAuthToken,
},
});
const { t } = useTranslation();
if (res.ok) {
try {
let plugin_export = await eval(await res.text());
@@ -243,14 +247,14 @@ class PluginLoader extends Logger {
version: version,
});
} catch (e) {
this.error(t('plugin_load_error', name), e);
this.error(t('PluginLoader.plugin_load_error', name), e);
const TheError: FC<{}> = () => (
<>
{t('error')}:{' '}
<pre>
<code>{e instanceof Error ? e.stack : JSON.stringify(e)}</code>
</pre>
<>{t('plugin_error_uninstall', <FaCog style={{ display: 'inline' }} />)}</>
<>{t('PluginLoader.plugin_error_uninstall', <FaCog style={{ display: 'inline' }} />)}</>
</>
);
this.plugins.push({
@@ -260,7 +264,7 @@ class PluginLoader extends Logger {
icon: <FaExclamationCircle />,
});
this.toaster.toast({
title: t('error_loading_plugin_toast', name),
title: t('PluginLoader.error_loading_plugin.toast', name),
body: '' + e,
icon: <FaExclamationCircle />,
});
@@ -296,12 +300,14 @@ class PluginLoader extends Logger {
includeFiles?: boolean,
regex?: RegExp,
): Promise<{ path: string; realpath: string }> {
const { t } = useTranslation();
return new Promise((resolve, reject) => {
const Content = ({ closeModal }: { closeModal?: () => void }) => (
// Purposely outside of the FilePicker component as lazy-loaded ModalRoots don't focus correctly
<ModalRoot
onCancel={() => {
reject(t('file_picker_cancel_text'));
reject(t('PluginLoader.file_picker_cancel_text'));
closeModal?.();
}}
>