Working backend, automatically swtich languages with steam and language fixes.

This commit is contained in:
Marco Rodolfi
2023-02-01 18:46:09 +01:00
parent 4732509728
commit b895f2c308
6 changed files with 47 additions and 41 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ def get_csrf_token():
@middleware @middleware
async def csrf_middleware(request, handler): 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("/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("/locales/") 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)):
return await handler(request) return await handler(request)
return Response(text='Forbidden', status='403') return Response(text='Forbidden', status='403')
+7
View File
@@ -1,5 +1,6 @@
from asyncio import Queue, sleep from asyncio import Queue, sleep
from json.decoder import JSONDecodeError from json.decoder import JSONDecodeError
from json import loads
from logging import getLogger from logging import getLogger
from os import listdir, path from os import listdir, path
from pathlib import Path from pathlib import Path
@@ -83,6 +84,7 @@ class Loader:
server_instance.add_routes([ server_instance.add_routes([
web.get("/frontend/{path:.*}", self.handle_frontend_assets), web.get("/frontend/{path:.*}", self.handle_frontend_assets),
web.get("/locales/{path:.*}", self.handle_frontend_locales),
web.get("/plugins", self.get_plugins), web.get("/plugins", self.get_plugins),
web.get("/plugins/{plugin_name}/frontend_bundle", self.handle_frontend_bundle), web.get("/plugins/{plugin_name}/frontend_bundle", self.handle_frontend_bundle),
web.post("/plugins/{plugin_name}/methods/{method_name}", self.handle_plugin_method_call), web.post("/plugins/{plugin_name}/methods/{method_name}", self.handle_plugin_method_call),
@@ -105,6 +107,11 @@ class Loader:
return web.FileResponse(file, headers={"Cache-Control": "no-cache"}) return web.FileResponse(file, headers={"Cache-Control": "no-cache"})
async def handle_frontend_locales(self, request):
file = path.join(path.dirname(__file__), "locales", request.match_info["path"])
return web.FileResponse(file, headers={"Cache-Control": "no-cache"})
async def get_plugins(self, request): async def get_plugins(self, request):
plugins = list(self.plugins.values()) plugins = list(self.plugins.values())
return web.json_response([{"name": str(i) if not i.legacy else "$LEGACY_"+str(i), "version": i.version} for i in plugins]) return web.json_response([{"name": str(i) if not i.legacy else "$LEGACY_"+str(i), "version": i.version} for i in plugins])
+1 -1
View File
@@ -37,5 +37,5 @@ export default function SettingsPage() {
route: '/decky/settings/developer', route: '/decky/settings/developer',
}); });
return <SidebarNavigation title={t('SettingsIndex.settings_navbar') as string} showTitle pages={pages} />; return <SidebarNavigation title={t('SettingsIndex.navbar_settings') as string} showTitle pages={pages} />;
} }
@@ -11,15 +11,16 @@ export default function DeveloperSettings() {
const [reactDevtoolsEnabled, setReactDevtoolsEnabled] = useSetting<boolean>('developer.rdt.enabled', false); const [reactDevtoolsEnabled, setReactDevtoolsEnabled] = useSetting<boolean>('developer.rdt.enabled', false);
const [reactDevtoolsIP, setReactDevtoolsIP] = useSetting<string>('developer.rdt.ip', ''); const [reactDevtoolsIP, setReactDevtoolsIP] = useSetting<string>('developer.rdt.ip', '');
const textRef = useRef<HTMLDivElement>(null); const textRef = useRef<HTMLDivElement>(null);
const { t } = useTranslation('DeveloperIndex'); const { t } = useTranslation();
return ( return (
<> <>
<Field <Field
label={t('valve_internal.label')} label={t('DeveloperIndex.valve_internal.label')}
description={ description={
<span style={{ whiteSpace: 'pre-line' }}> <span style={{ whiteSpace: 'pre-line' }}>
{t('valve_internal.desc1')} <span style={{ color: 'red' }}>{t('valve_internal.desc2')}</span> {t('DeveloperIndex.valve_internal.desc1')}{' '}
<span style={{ color: 'red' }}>{t('DeveloperIndex.valve_internal.desc2')}</span>
</span> </span>
} }
icon={<FaSteamSymbol style={{ display: 'block' }} />} icon={<FaSteamSymbol style={{ display: 'block' }} />}
@@ -56,10 +57,10 @@ export default function DeveloperSettings() {
} }
> >
<Field <Field
label={t('react_devtools.label')} label={t('DeveloperIndex.react_devtools.label')}
description={ description={
<> <>
<span style={{ whiteSpace: 'pre-line' }}>{t('react_devtools.desc')}</span> <span style={{ whiteSpace: 'pre-line' }}>{t('DeveloperIndex.react_devtools.desc')}</span>
<div ref={textRef}> <div ref={textRef}>
<TextField label={'IP'} value={reactDevtoolsIP} onChange={(e) => setReactDevtoolsIP(e?.target.value)} /> <TextField label={'IP'} value={reactDevtoolsIP} onChange={(e) => setReactDevtoolsIP(e?.target.value)} />
</div> </div>
-31
View File
@@ -1,31 +0,0 @@
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import Backend from 'i18next-http-backend';
import { initReactI18next } from 'react-i18next';
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
load: 'languageOnly',
debug: true,
fallbackLng: 'en',
lng: 'it',
interpolation: {
escapeValue: false,
},
backend: {
loadPath: 'http://127.0.0.1:1337/locales/{{lng}}.json',
requestOptions: {
// used for fetch
credentials: 'include',
cache: 'no-cache',
},
customHeaders: {
Authentication: window.deckyAuthToken,
},
},
});
export default i18n;
+32 -3
View File
@@ -1,6 +1,8 @@
import './i18n';
import { Navigation, Router, sleep } from 'decky-frontend-lib'; import { Navigation, Router, sleep } from 'decky-frontend-lib';
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import Backend from 'i18next-http-backend';
import { initReactI18next } from 'react-i18next';
import PluginLoader from './plugin-loader'; import PluginLoader from './plugin-loader';
import { DeckyUpdater } from './updater'; import { DeckyUpdater } from './updater';
@@ -38,9 +40,34 @@ declare global {
(async () => { (async () => {
window.deckyAuthToken = await fetch('http://127.0.0.1:1337/auth/token').then((r) => r.text()); window.deckyAuthToken = await fetch('http://127.0.0.1:1337/auth/token').then((r) => r.text());
i18n
.use(Backend)
.use(LanguageDetector)
.use(initReactI18next)
.init({
load: 'languageOnly',
detection: {
order: ['querystring', 'navigator'],
lookupQuerystring: 'lng',
},
debug: true,
fallbackLng: 'en',
interpolation: {
escapeValue: false,
},
backend: {
loadPath: 'http://127.0.0.1:1337/locales/{{lng}}.json',
customHeaders: {
Authentication: window.deckyAuthToken,
},
requestOptions: {
credentials: 'include',
},
},
});
window.DeckyPluginLoader?.dismountAll(); window.DeckyPluginLoader?.dismountAll();
window.DeckyPluginLoader?.deinit(); window.DeckyPluginLoader?.deinit();
window.DeckyPluginLoader = new PluginLoader(); window.DeckyPluginLoader = new PluginLoader();
window.DeckyPluginLoader.init(); window.DeckyPluginLoader.init();
window.importDeckyPlugin = function (name: string, version: string) { window.importDeckyPlugin = function (name: string, version: string) {
@@ -63,3 +90,5 @@ declare global {
setTimeout(() => window.syncDeckyPlugins(), 5000); setTimeout(() => window.syncDeckyPlugins(), 5000);
})(); })();
export default i18n;