diff options
| author | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2025-07-19 13:33:22 -0400 |
|---|---|---|
| committer | xXJSONDeruloXx <danielhimebauch@gmail.com> | 2025-07-19 13:33:22 -0400 |
| commit | bf042515f4c90b951bcd323eb21a54c8ac8fada2 (patch) | |
| tree | f3a321ff7d75bb840449a69a5db39a960329b7ce /src | |
| parent | d1d5223e04a037c4ad08f5d4588ec86204ddda52 (diff) | |
| download | decky-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.ts | 9 | ||||
| -rw-r--r-- | src/components/NerdStuffModal.tsx | 149 |
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> )} </> )} |
