summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorxXJSONDeruloXx <danielhimebauch@gmail.com>2025-07-19 13:33:22 -0400
committerxXJSONDeruloXx <danielhimebauch@gmail.com>2025-07-19 13:33:22 -0400
commitbf042515f4c90b951bcd323eb21a54c8ac8fada2 (patch)
treef3a321ff7d75bb840449a69a5db39a960329b7ce /src
parentd1d5223e04a037c4ad08f5d4588ec86204ddda52 (diff)
downloaddecky-lsfg-vk-bf042515f4c90b951bcd323eb21a54c8ac8fada2.tar.gz
decky-lsfg-vk-bf042515f4c90b951bcd323eb21a54c8ac8fada2.zip
add script and conf views to nerd modal
Diffstat (limited to 'src')
-rw-r--r--src/api/lsfgApi.ts9
-rw-r--r--src/components/NerdStuffModal.tsx149
2 files changed, 122 insertions, 36 deletions
diff --git a/src/api/lsfgApi.ts b/src/api/lsfgApi.ts
index 4c23955..74caa57 100644
--- a/src/api/lsfgApi.ts
+++ b/src/api/lsfgApi.ts
@@ -80,6 +80,13 @@ export interface LaunchOptionResult {
explanation: string;
}
+export interface FileContentResult {
+ success: boolean;
+ content?: string;
+ path?: string;
+ error?: string;
+}
+
// API functions
export const installLsfgVk = callable<[], InstallationResult>("install_lsfg_vk");
export const uninstallLsfgVk = callable<[], InstallationResult>("uninstall_lsfg_vk");
@@ -89,6 +96,8 @@ export const getDllStats = callable<[], DllStatsResult>("get_dll_stats");
export const getLsfgConfig = callable<[], ConfigResult>("get_lsfg_config");
export const getConfigSchema = callable<[], ConfigSchemaResult>("get_config_schema");
export const getLaunchOption = callable<[], LaunchOptionResult>("get_launch_option");
+export const getConfigFileContent = callable<[], FileContentResult>("get_config_file_content");
+export const getLaunchScriptContent = callable<[], FileContentResult>("get_launch_script_content");
// Updated config function using centralized configuration
export const updateLsfgConfig = callable<
diff --git a/src/components/NerdStuffModal.tsx b/src/components/NerdStuffModal.tsx
index 4dd53b1..104e772 100644
--- a/src/components/NerdStuffModal.tsx
+++ b/src/components/NerdStuffModal.tsx
@@ -4,7 +4,7 @@ import {
Field,
Focusable
} from "@decky/ui";
-import { getDllStats, DllStatsResult } from "../api/lsfgApi";
+import { getDllStats, DllStatsResult, getConfigFileContent, getLaunchScriptContent, FileContentResult } from "../api/lsfgApi";
interface NerdStuffModalProps {
closeModal?: () => void;
@@ -12,24 +12,35 @@ interface NerdStuffModalProps {
export function NerdStuffModal({ closeModal }: NerdStuffModalProps) {
const [dllStats, setDllStats] = useState<DllStatsResult | null>(null);
+ const [configContent, setConfigContent] = useState<FileContentResult | null>(null);
+ const [scriptContent, setScriptContent] = useState<FileContentResult | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
- const loadDllStats = async () => {
+ const loadData = async () => {
try {
setLoading(true);
setError(null);
- const result = await getDllStats();
- setDllStats(result);
+
+ // Load all data in parallel
+ const [dllResult, configResult, scriptResult] = await Promise.all([
+ getDllStats(),
+ getConfigFileContent(),
+ getLaunchScriptContent()
+ ]);
+
+ setDllStats(dllResult);
+ setConfigContent(configResult);
+ setScriptContent(scriptResult);
} catch (err) {
- setError(err instanceof Error ? err.message : "Failed to load DLL stats");
+ setError(err instanceof Error ? err.message : "Failed to load data");
} finally {
setLoading(false);
}
};
- loadDllStats();
+ loadData();
}, []);
const formatSHA256 = (hash: string) => {
@@ -49,44 +60,110 @@ export function NerdStuffModal({ closeModal }: NerdStuffModalProps) {
return (
<ModalRoot onCancel={closeModal} onOK={closeModal}>
{loading && (
- <div>Loading DLL information...</div>
+ <div>Loading information...</div>
)}
{error && (
<div>Error: {error}</div>
)}
- {!loading && !error && dllStats && (
+ {!loading && !error && (
<>
- {!dllStats.success ? (
- <div>{dllStats.error || "Failed to get DLL stats"}</div>
- ) : (
- <div>
- <Field label="DLL Path">
- <Focusable
- onClick={() => dllStats.dll_path && copyToClipboard(dllStats.dll_path)}
- onActivate={() => dllStats.dll_path && copyToClipboard(dllStats.dll_path)}
- >
- {dllStats.dll_path || "Not available"}
- </Focusable>
- </Field>
-
- <Field label="SHA256 Hash">
- <Focusable
- onClick={() => dllStats.dll_sha256 && copyToClipboard(dllStats.dll_sha256)}
- onActivate={() => dllStats.dll_sha256 && copyToClipboard(dllStats.dll_sha256)}
- >
- {dllStats.dll_sha256 ? formatSHA256(dllStats.dll_sha256) : "Not available"}
- </Focusable>
- </Field>
-
- {dllStats.dll_source && (
- <Field label="Detection Source">
- <div>{dllStats.dll_source}</div>
- </Field>
+ {/* DLL Stats Section */}
+ {dllStats && (
+ <>
+ {!dllStats.success ? (
+ <div>{dllStats.error || "Failed to get DLL stats"}</div>
+ ) : (
+ <div>
+ <Field label="DLL Path">
+ <Focusable
+ onClick={() => dllStats.dll_path && copyToClipboard(dllStats.dll_path)}
+ onActivate={() => dllStats.dll_path && copyToClipboard(dllStats.dll_path)}
+ >
+ {dllStats.dll_path || "Not available"}
+ </Focusable>
+ </Field>
+
+ <Field label="SHA256 Hash">
+ <Focusable
+ onClick={() => dllStats.dll_sha256 && copyToClipboard(dllStats.dll_sha256)}
+ onActivate={() => dllStats.dll_sha256 && copyToClipboard(dllStats.dll_sha256)}
+ >
+ {dllStats.dll_sha256 ? formatSHA256(dllStats.dll_sha256) : "Not available"}
+ </Focusable>
+ </Field>
+
+ {dllStats.dll_source && (
+ <Field label="Detection Source">
+ <div>{dllStats.dll_source}</div>
+ </Field>
+ )}
+ </div>
)}
-
- </div>
+ </>
+ )}
+
+ {/* Launch Script Section */}
+ {scriptContent && (
+ <Field label="Launch Script">
+ {!scriptContent.success ? (
+ <div>Script not found: {scriptContent.error}</div>
+ ) : (
+ <div>
+ <div style={{ marginBottom: "8px", fontSize: "0.9em", opacity: 0.8 }}>
+ Path: {scriptContent.path}
+ </div>
+ <Focusable
+ onClick={() => scriptContent.content && copyToClipboard(scriptContent.content)}
+ onActivate={() => scriptContent.content && copyToClipboard(scriptContent.content)}
+ >
+ <pre style={{
+ background: "rgba(255, 255, 255, 0.1)",
+ padding: "8px",
+ borderRadius: "4px",
+ fontSize: "0.8em",
+ whiteSpace: "pre-wrap",
+ overflow: "auto",
+ maxHeight: "150px"
+ }}>
+ {scriptContent.content || "No content"}
+ </pre>
+ </Focusable>
+ </div>
+ )}
+ </Field>
+ )}
+
+ {/* Config File Section */}
+ {configContent && (
+ <Field label="Configuration File">
+ {!configContent.success ? (
+ <div>Config not found: {configContent.error}</div>
+ ) : (
+ <div>
+ <div style={{ marginBottom: "8px", fontSize: "0.9em", opacity: 0.8 }}>
+ Path: {configContent.path}
+ </div>
+ <Focusable
+ onClick={() => configContent.content && copyToClipboard(configContent.content)}
+ onActivate={() => configContent.content && copyToClipboard(configContent.content)}
+ >
+ <pre style={{
+ background: "rgba(255, 255, 255, 0.1)",
+ padding: "8px",
+ borderRadius: "4px",
+ fontSize: "0.8em",
+ whiteSpace: "pre-wrap",
+ overflow: "auto",
+ maxHeight: "200px"
+ }}>
+ {configContent.content || "No content"}
+ </pre>
+ </Focusable>
+ </div>
+ )}
+ </Field>
)}
</>
)}