import { parseCommand } from "components/apps/Terminal/functions"; import type { ComponentProcessProps } from "components/system/Apps/RenderComponent"; import StyledRun from "components/system/Dialogs/Run/StyledRun"; import StyledButton from "components/system/Dialogs/Transfer/StyledButton"; import { getProcessByFileExtension, getShortcutInfo, } from "components/system/Files/FileEntry/functions"; import useFileDrop from "components/system/Files/FileManager/useFileDrop"; import { useFileSystem } from "contexts/fileSystem"; import { useProcesses } from "contexts/process"; import processDirectory from "contexts/process/directory"; import { useSession } from "contexts/session"; import { basename, extname, join } from "path"; import { useCallback, useLayoutEffect, useRef, useState } from "react"; import { DESKTOP_PATH, PACKAGE_DATA, PREVENT_SCROLL, SHORTCUT_EXTENSION, } from "utils/constants"; import { haltEvent } from "utils/functions"; import { getIpfsFileName, getIpfsResource } from "utils/ipfs"; import spawnSheep from "utils/spawnSheep"; const OPEN_ID = "open"; const resourceAliasMap: Record = { cmd: "Terminal", dos: "JSDOS", explorer: "FileExplorer", monaco: "MonacoEditor", mspaint: "Paint", vlc: "VideoPlayer", }; const MESSAGE = `Digite o nome de um programa, pasta, documento ou recurso da Internet e ${PACKAGE_DATA.alias} vai abrir para você.`; const notFound = (resource: string): void => // eslint-disable-next-line no-alert alert( `Não foi possível encontrar '${resource}'. Certifique-se de ter digitado o nome corretamente e tente novamente.` ); const utilCommandMap: Record void> = { esheep: spawnSheep, sheep: spawnSheep, }; const Run: FC = () => { const { open, closeWithTransition, processes: { Run: runProcess } = {}, } = useProcesses(); const { createPath, exists, readFile, stat, updateFolder } = useFileSystem(); const { foregroundId, runHistory, setRunHistory } = useSession(); const inputRef = useRef(null); const [isInputFocused, setIsInputFocused] = useState(true); const [isEmptyInput, setIsEmptyInput] = useState(!runHistory[0]); const [running, setRunning] = useState(false); const runResource = useCallback( async (resource?: string) => { if (!resource) return; setRunning(true); const addRunHistoryEntry = (): void => setRunHistory((currentRunHistory) => currentRunHistory[0] === resource ? currentRunHistory : [resource, ...currentRunHistory] ); const [resourcePid, ...resourceUrl] = parseCommand(resource); let resourcePath = resource; let closeOnExecute = true; const resourceExists = await exists(resourcePath); if (!resourceExists) { resourcePath = resourceUrl.length > 0 ? resourceUrl.join(" ") : resourcePid; } const isIpfs = resourcePath.startsWith("ipfs://"); if (resourceExists || isIpfs || (await exists(resourcePath))) { if (isIpfs) { try { const ipfsData = await getIpfsResource(resourcePath); resourcePath = join( DESKTOP_PATH, await createPath( await getIpfsFileName(resourcePath, ipfsData), DESKTOP_PATH, ipfsData ) ); updateFolder(DESKTOP_PATH, basename(resourcePath)); } catch { // Ignore failure to get ipfs resource } } const stats = await stat(resourcePath); if (stats.isDirectory()) { open("FileExplorer", { url: resourcePath }, ""); addRunHistoryEntry(); } else if ( resourcePid && resourceUrl.length > 0 && resourcePath !== resource ) { const pid = Object.keys(processDirectory).find( (processName) => processName.toLowerCase() === resourcePid.toLowerCase() ); if (pid) { open(pid, { url: pid === "Browser" && isIpfs ? resourceUrl.join(" ") : resourcePath, }); addRunHistoryEntry(); } else { notFound(resourcePid); closeOnExecute = false; } } else { const extension = extname(resourcePath); if (extension === SHORTCUT_EXTENSION) { const { pid, url } = getShortcutInfo(await readFile(resourcePath)); if (pid) open(pid, { url }); } else { const basePid = getProcessByFileExtension(extension); if (basePid) { open(basePid, { url: basePid === "Browser" && isIpfs ? resource : resourcePath, }); } } addRunHistoryEntry(); } } else { const pid = Object.keys(processDirectory).find( (processName) => processName.toLowerCase() === ( resourceAliasMap[resourcePath.toLowerCase()] || resourcePath ).toLowerCase() ); if (pid) { open(pid); addRunHistoryEntry(); } else if (utilCommandMap[resource.toLowerCase()]) { utilCommandMap[resource.toLowerCase()](); addRunHistoryEntry(); } else { notFound(resource); closeOnExecute = false; } } setRunning(false); if (closeOnExecute) closeWithTransition("Run"); }, [ closeWithTransition, createPath, exists, open, readFile, setRunHistory, stat, updateFolder, ] ); useLayoutEffect(() => { if (foregroundId === "Run") { inputRef.current?.focus(PREVENT_SCROLL); if (inputRef.current?.value) inputRef.current?.select(); } }, [foregroundId]); useLayoutEffect(() => { if (runProcess?.url && inputRef.current) { inputRef.current.value = `${inputRef.current.value.trimEnd()} ${ runProcess.url }`.trim(); setIsEmptyInput(false); } }, [runProcess?.url]); return ( { if (!(event.target instanceof HTMLInputElement)) { haltEvent(event); } }} >
Executar
{MESSAGE}
{ if ( !runProcess?.componentWindow || runProcess.componentWindow.contains(relatedTarget) ) { inputRef.current?.focus(PREVENT_SCROLL); } else { setIsInputFocused(false); } }} onFocusCapture={() => setIsInputFocused(true)} onKeyDownCapture={(event) => { const { key } = event; if (key === "Enter") runResource(inputRef.current?.value.trim()); if (key === "Escape") { haltEvent(event); closeWithTransition("Run"); } }} onKeyUp={({ target }) => setIsEmptyInput(!(target as HTMLInputElement)?.value) } spellCheck="false" type="text" />
); }; export default Run;