diff --git a/src/main/installer.ts b/src/main/installer.ts index 59526be..feedc6d 100644 --- a/src/main/installer.ts +++ b/src/main/installer.ts @@ -3,12 +3,11 @@ import { exec } from 'child_process' import { join } from 'path' import { ipcMain, WebContents } from 'electron' import { glob } from 'glob' -import { mkdirSync, statSync, unlinkSync } from 'fs' +import { mkdirSync, statSync, unlinkSync, readdirSync } from 'fs' import { installTasks, InstallTask, updateInstallTask, InstallProgressPeriod } from './tasks' import { downloadAssets } from './downloader' import { setAppRecord } from './library' -import { readdirSync } from 'original-fs' export function initInstaller(): void { ipcMain.handle('install-product-release', (evt, task: string) => submitInstallTask(JSON.parse(task), evt.sender)) diff --git a/src/main/library.ts b/src/main/library.ts index d1db2cf..e78a971 100644 --- a/src/main/library.ts +++ b/src/main/library.ts @@ -44,6 +44,7 @@ export function initLibrary(): void { JSON.stringify(getAppLibrary().filter((ele) => ele.id === id)[0]), ) + ipcMain.handle('uninstall-app', (_, id: string) => uninstallApp(id)) ipcMain.handle('launch-app', (_, id: string) => launchApp(id)) } @@ -68,6 +69,24 @@ export function setAppRecord(record: LocalAppRecord) { saveLocalLibrary() } +export function removeAppRecord(id: string) { + let current = getAppLibrary() + current = current.filter((rec) => rec.id !== id) + + library.apps = current + saveLocalLibrary() +} + +export function uninstallApp(id: string) { + const app = getAppLibrary().filter((ele) => ele.id === id)[0] + if (!app) return + + const basePath = app.basePath + fs.rmdirSync(basePath, { recursive: true }) + + removeAppRecord(id) +} + export function launchApp(id: string): void { const app = getAppLibrary().filter((ele) => ele.id === id)[0] if (!app) return @@ -78,7 +97,7 @@ export function launchApp(id: string): void { const segments = runner.script.split(' ') try { - spawn(segments[0], segments.slice(1), { + spawn(segments[0], segments.length > 1 ? segments.slice(1) : [], { detached: true, cwd: runner.workdir ? join(app.basePath, runner.workdir) : app.basePath, }) diff --git a/src/renderer/src/pages/Landing.tsx b/src/renderer/src/pages/Landing.tsx index 02d11a6..914f523 100644 --- a/src/renderer/src/pages/Landing.tsx +++ b/src/renderer/src/pages/Landing.tsx @@ -34,7 +34,7 @@ export default function Landing(): JSX.Element { return ( - + Matrix Marketplace diff --git a/src/renderer/src/pages/library/Details.tsx b/src/renderer/src/pages/library/Details.tsx index 1eebaf8..293ff5f 100644 --- a/src/renderer/src/pages/library/Details.tsx +++ b/src/renderer/src/pages/library/Details.tsx @@ -6,6 +6,7 @@ import { getAttachmentUrl } from 'solar-js-sdk' import { parseContent } from '@renderer/services/parser' import PlayIcon from '@mui/icons-material/PlayArrow' +import UninstallIcon from '@mui/icons-material/Delete' import ArrowBackwardIcon from '@mui/icons-material/ArrowBack' export default function LibraryDetails(): JSX.Element { @@ -16,6 +17,8 @@ export default function LibraryDetails(): JSX.Element { const [appProductContent, setAppProductContent] = useState() const [appReleaseContent, setAppReleaseContent] = useState() + const [busy, setBusy] = useState(false) + const product = useMemo(() => app?.product, [app]) function fetchApp() { @@ -40,8 +43,21 @@ export default function LibraryDetails(): JSX.Element { } }, [app]) - function launchApp() { - window.electron.ipcRenderer.invoke('launch-app', app?.id) + async function uninstallApp() { + const yes = confirm(`Are you sure to uninstall this app ${app?.product.name} version ${app?.release.version}?`) + if (!yes) return + + setBusy(true) + await window.electron.ipcRenderer.invoke('uninstall-app', app?.id) + setBusy(false) + + navigate('/library') + } + + async function launchApp() { + setBusy(true) + await window.electron.ipcRenderer.invoke('launch-app', app?.id) + setBusy(false) } return ( @@ -116,7 +132,10 @@ export default function LibraryDetails(): JSX.Element { - + + + +